<?php
/**
 * Richard Framework - Services::MMS
 *
 * MMS Functionalities
 *
 * @author    Mark Soriano
 * @copyright I-Payment Solutions Philippines
 * @package   Services::MMS
 * @version   0.1.0
 *
 * @todo      ToDo's
 *            - Incomplete methods/funtionalities
 */
 
require_once "Richard/Exception.php";
require_once "Richard/Crypt/REDS.php";
 
class Richard_Modules_MMS
{
   /**
     * USER TYPES DEFINITIONS
     */
   const     USER_TYPE_ROOT        = 1;
   const     USER_TYPE_SUPERADMIN  = 2;
   const     USER_TYPE_BRANCHADMIN = 3;
   const     USER_TYPE_USER        = 4;
 
   /**
     * Application ID (Please dont change!)
     *
     * @var    int
     * @access private
     */
   private   $_app_id              = 2;
 
   /**
     * Array of user information
     *
     * @var    array
     * @access private
     */
   private   $_session_vars        = array('userid' => '',
                                           'ip'     => ''
                                           );
   /**
     * instance of the database connection
     *
     * @var    object
     * @access private
     */
   private   $_db_rex2;
 
   /**
     * The return value of this class
     *
     * @var    bool
     * @access private
     */
   private   $_return              = false;
 
   /**
     * The error message holder
     *
     * @var    string
     * @access public
     */
   public    $_error;
 
   /**
     * The error code
     * @var    string
     * @access public
     */
   public    $_errorcode = '911000';
 
   /**
     * The var holding all values submitted into
     * the method
     *
     * @var    array
     * @access protected
     */
   protected $_values;
 
   /**
     * The transaction data
     *
     * @var    array
     * @access protected
     */
   protected $_values_data;
 
   /**
     * Response data holder
     */
 
   protected $_respdata;
   
   //loyalty method = 4 = MMS
   public $loyalty_method = '4';
 
   /**
     * The class contruct method, it just initialize
     * the database connection
     *
     * @access public
     * @return void
     */
   public function __construct()
   {
       require_once "Richard/Db.php";
 
       $db             = new Richard_Db();
       $this->_db_rex2 = $db->connect('REX2');
   }
 
   public function getResponseData()
   {
       return $this->_respdata;
   }
   /**
     * Get all MMS application Actions
     *
     * @access public
     * @return array
     */
   public function getMMSAppActions()
   {
       $stmt = $this->_db_rex2->query("SELECT *
                                         FROM applications_actions
                                        WHERE appid = '" . $this->_app_id . "'
                                     ORDER BY actioncode ASC");
       return $stmt->fetchAll();
 
   }
 
   /**
     * Get merchant list, if empty arg (mmsid) then it will
     * return all merchants
     *
     * @access public
     * @param  int $mmsid
     * @return array
     */
   public function getMerchantsList($mmsid = '')
   {
       if (empty($mmsid)) {
           $stmt = $this->_db_rex2->query("SELECT *
                                             FROM merchant
                                         ORDER BY name ASC");
       } else {
           $stmt = $this->_db_rex2->query("SELECT *
                                             FROM merchant
                                            WHERE mmsid = '" . $mmsid . "'
                                         ORDER BY name ASC");
       }
       return $stmt->fetchAll();
   }
 
   /**
     * Get merchant adjustment types
     *
     * @access public
     * @return array
     */
   public function getMerchantAdjustmentTypes()
   {
 
       $stmt = $this->_db_rex2->query("SELECT *
                                         FROM merchant_adjustment_types
                                     ORDER BY adjustment_name ASC");
       return $stmt->fetchAll();
   }
 
   public function getMerchantAllowedMSF($merchantid = '')
   {
       $stmt = $this->_db_rex2->query("SELECT P.*
                                         FROM merchant_binaccess M, programs P
                                        WHERE M.merchantid = '$merchantid'
                                          AND M.programid  = P.id
                                          AND P.programtype = 'P06'");
 
       $res = $stmt->fetchAll();
 
       if (count($res) > 0) {
           return $res;
       } else {
           $stmt2 = $this->_db_rex2->query("SELECT *
                                              FROM programs
                                             WHERE programtype = 'P06'");
           return $stmt2->fetchAll();
       }
 
   }
 
   /**
     * Get branch list or informations, if merchant is not
     * specified it will return all branches per merchant
     *
     * @access public
     * @param  string $merchantid
     * @return array
     */
   public function getBranchList($merchantid = '')
   {
       if (empty($merchantid)) {
           $stmt = $this->_db_rex2->query("SELECT *
                                             FROM merchant_branches
                                         ORDER BY name ASC");
       } else {
           $stmt = $this->_db_rex2->query("SELECT *
                                             FROM merchant_branches
                                            WHERE merchantid = '" . $merchantid . "'
                                         ORDER BY name ASC");
       }
       return $stmt->fetchAll();
   }
 
   /**
     * Get MMS permissions by MMS ID specified
     *
     * @access public
     * @param  int $mmsid
     * @return array
     */
   public function getMMSPermissionsByMMSid($mmsid)
   {
       $perms = array();
       if (!empty($mmsid)) {
           $stmt = $this->_db_rex2->query("SELECT A.id, A.actiondesc, A.actioncode
                                             FROM permissions P, applications_actions A
                                            WHERE P.pid = '$mmsid'                   AND
                                                  P.userid is NULL                   AND
                                                  P.appid = '" . $this->_app_id . "' AND
                                                  P.actionid = A.id                  AND
                                                  P.appid = A.appid
                                         ORDER BY A.actioncode ASC");
           $result = $stmt->fetchAll();
           if (count($result) > 0) {
               $perms = $result;
           }
       }
 
       return $perms;
   }
 
   /**
     * Get the MMS user types (e.g. control user, merchant admin, etc)
     *
     * @access public
     * @return array
     */
   public function getMMSUserTypes()
   {
       $stmt = $this->_db_rex2->query("SELECT *
                                         FROM merchant_users_types
                                        WHERE usertype <> 1
                                     ORDER BY usertype ASC");
       return $stmt->fetchAll();
   }
 
   /**
     * Get the Salary Bracket
     *
     * @access public
     * @return array
     */
   public function getSalaryBracket($values = array())
   {
       $this->_values      =& $values;
 
       if($this->_values['currency'] || $this->_values['country']) {
               $sql = '';
               $array_datakeys = array_keys($this->_values);
 
               $count = 0;
               foreach ($this->_values as $dataval) {
                       if($dataval) {
                               $count++;
                       }
               }
 
               $x = 0;
               while ($x < $count) {
                       if($this->_values[$array_datakeys[$x]]) {
                                $i = $x + 1;
                                if($i == $count) {
                                        $sql .= $array_datakeys[$x] . " LIKE '" . strtoupper($this->_values[$array_datakeys[$x]]) . "'";
                                } else {
                                        $sql .= $array_datakeys[$x] . " LIKE '" . strtoupper($this->_values[$array_datakeys[$x]]) . "' OR ";
                                }
                       }
                       $x++;
               }
 
               $stmt = $this->_db_rex2->query("SELECT * FROM amla_salary_bracket WHERE " . $sql);
                $result = $stmt->fetchAll();
                if(count($result) > 0) {
                        foreach ($result as $data) {
                                         mmsid    = '" .  $this->_values_data['mmsid'] . "' AND
                                         merchantid = '" .  $this->_values_data['merchantid'] . "' AND
                                         branchid   = 0
                                   LIMIT 0, 1
                                   ";
               break;
           case self::USER_TYPE_BRANCHADMIN:
           case self::USER_TYPE_USER:
               $user_qry_check = "SELECT username
                                    FROM merchant_users
                                   WHERE username = '" .  Richard_Crypt_REDS::login($this->_values_data['username'],'ENCRYPT') . "' AND
                                         mmsid    = '" .  $this->_values_data['mmsid'] . "' AND
                                         merchantid = '" .  $this->_values_data['merchantid'] . "' AND
                                         branchid   = '" .  $this->_values_data['branchid'] . "'
                                   LIMIT 0, 1
                                   ";
               break;
       }
 
       $check_username_stmt = $this->_db_rex2->query($user_qry_check);
 
       if (count($check_username_stmt->fetchAll()) > 0) {
           $this->_raiseError(__METHOD__,"Username already taken under this merchant/mms/branch",3003);
           return false;
       }
       // }}}
 
       // Create a strong password then encrypt it
       $password = Richard_System_Utility::make_password(8);
 
       // TEMP For clean username and password
       require_once "Zend/Log.php";
       require_once "Zend/Log/Writer/Stream.php";
 
       require_once "Richard/System/Settings.php";
       $stream       = @fopen(Richard_System_Settings::MMS_LOG_PATH . "up.log", 'a', false);
 
       $writer       = new Zend_Log_Writer_Stream($stream);
       $logger       = new Zend_Log($writer);
 
       // {{{ Send Email
       require_once 'Mail.php';
       require_once 'Mail/mime.php';
       require_once "Richard/System/Settings.php";
       $mail_settings = Richard_System_Settings::mail('do-not-reply@rexplatform.com');
       
       switch ($this->_values_data['usertype']) {
           case 1:
               $user_type = "ROOT";
               break;
           case 2:
               $user_type = "Merchant Super Admin";
               break;
           case 3:
               $user_type = "Merchant Branch Admin";
               break;
           case 4:
               $user_type = "Branch User";
               break;
           default:
               break;
       }
 
       $merchant_info = "
                Merchant ID: " . $this->_values_data['merchantid'] . "<br />
                Branch ID: " . $this->_values_data['branchid'] . "<br />
               ";
       if ($this->_values['type'] == 'custom') {
           $merchant_info = "
                User Type: " . $user_type . "<br />
                Merchant ID: " . $this->_values_data['merchantid'] . "<br />
                Branch ID: " . $this->_values_data['branchid'] . "<br />
           ";
       }
       
       $html = "<html><body>Auto-generated Email. Please do not reply. <br /><br />
                <p><b>Your MMS Credentials</b></p>
                {$merchant_info}
                Username: " . $this->_values_data['username'] . "<br />
                Password: " . $password . "<br />
                <br />
                <p>Important: Please change your password immediately after first log-in</p>
                </body></html>";
 
       $hdrs = array(
                     'From'    => 'do-not-reply@rexplatform.com',
                     'To'              => $this->_values_data['email'],
                     'Subject' => 'MMS Login Details'
                     );
       $crlf = "\n";
 
       $mime = new Mail_mime($crlf);
       $mime->setHTMLBody($html);
 
       //do not ever try to call these lines in reverse order
       $body = $mime->get();
       $hdrs = $mime->headers($hdrs);
 
       /* Create the mail object using the Mail::factory method */
       $mail_object =& Mail::factory("mail");
           return false;
       }
 
       return $merchant_data;
   }
 
   /**
     * Get Merchant Info via Alias
     */
   public function getMerchantInfoByAlias($alias)
   {
       $select = "SELECT *
                    FROM merchant
                   WHERE alias = '" . $alias . "'
                   LIMIT 0, 1
                   ";
 
       $stmt = $this->_db_rex2->query($select);
       $merchant_data = $stmt->fetchAll();
       if (count($merchant_data) < 1) {
           $this->_raiseError(__METHOD__,'This merchant alias does not exists.',3012);
           return false;
       }
 
       return $merchant_data;
   }
 
   /**
     * HELP!!
     *
     * @param unknown_type $values
     */
   public function getMerchants($values = array())
   {
       $this->_values = $values;
   }
 
   /**
     * HELP!!
     *
     * @param unknown_type $values
     */
   public function getBranches($values = array())
   {
       $this->_values = $values;
   }
 
   /**
     * HELP!!
     *
     * @param unknown_type $values
     */
   public function getUsers($values = array())
   {
       $this->_values = $values;
   }
 
   /**
     * HELP!!
     *
     * @param unknown_type $values
     */
   public function getBranchInfo($values = array())
   {
       $this->_values = $values;
   }
 
   /**
     * HELP!!
     *
     * @param unknown_type $values
     */
   public function getUserInfo($values = array())
   {
       $this->_values = $values;
 
   }
 
   /**
     * HELP!!
     *
     * @param unknown_type $values
     */
   public function deleteMerchant($values = array())
   {
       $this->_values = $values;
 
   }
 
   /**
     * HELP!!
     *
     * @param unknown_type $values
     */
   public function deleteBranch($values = array())
   {
       $this->_values = $values;
 
   }
 
       $user_id      = $user_info[2];
 
       $actioncodes  = array();
 
       $actions_stmt = "SELECT A.actioncode
                          FROM permissions P, applications_actions A
                         WHERE P.userid   = '$user_id' AND
                               P.actionid = A.id
                       ";
 
       $stmt         = $this->_db_rex2->query($actions_stmt);
       $actioncodes_res = $stmt->fetchAll();
 
       if (count($actioncodes_res) > 0) {
           foreach ($actioncodes_res as $values) {
               $actioncodes[] = $values['actioncode'];
           }
       }
 
       return $actioncodes;
   }
 
   /**
     * Get User Actions by Permission, Richard System ACL
     * table merchant_users_types or the const definition
     * on the top of this file
     *
     * @access public
     * @param  array $app,$pid,$userid
     * @return mixed
     */
 
        public function getUserActionsPermission($values = array()){
 
                $this->_values =& $values['data'];
 
                require_once "Richard/System/ACL.php";
 
                $acl = new Richard_System_ACL();
 
                $response = $acl->getActionByUsers($this->_values['appid'],$this->_values['userid'],$this->_values['userTypeId']);
                if(!is_array($response)){
                        $this->_raiseError(__METHOD__,'Unable to get details, please try again.','1234');
           return false;
                }
 
                return $response;
        }
 
   /**
     * Get User Type, please see REX2 Database and
     * table merchant_users_types or the const definition
     * on the top of this file
     *
     * @access public
     * @param  string $sessionid
     * @return mixed
     */
 
 
   public function getUserType($sessionid)
   {
       require_once "Richard/Services/SessionHandler.php";
 
       $sess         = new Services_SessionHandler();
       $user_info    = $sess->decryptSessionID($sessionid);
       $user_id      = $user_info[2];
 
       $actions_stmt = "SELECT usertype
                          FROM merchant_users
                         WHERE id   = '$user_id'
                         LIMIT 0, 1
                       ";
 
       $stmt         = $this->_db_rex2->query($actions_stmt);
       $user_data = $stmt->fetchAll();
 
       if (count($user_data) > 0) {
           return $user_data[0]['usertype'];
       }
 
       return false;
   }
 
   /**
     * Get Card Account Profile
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function getCardProfile($values)
   {
       require_once "Richard/Crypt/REDS.php";
       require_once "Richard/Modules/CardFunctions.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.getprofile";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
       
       // agex like apps. uses mobile in profile search.
       $cardprofile = null;
       if (strlen($this->_values['cardnumber']) <> 16) {
               
               require_once "Richard/System/Core.php";
               require_once "Richard/Crypt/RKMS.php";
               
               $cardprofile = Richard_System_Core::getCardProfileByMobile(
                       $this->_values['cardnumber']);
               
               if (!$cardprofile) {
                       $this->_raiseError(__METHOD__, 'Profile Mobile Number not found', 3087);
                       return false;
               }
               $rkms = new Richard_Crypt_RKMS();
               
               $cardnumber = $rkms->decryptByDKID($cardprofile['cardkeyid'],
                               $cardprofile['cardnumber']);
               
               if (!$cardnumber) {
                       $message = "Account not found!";
                       $this->_raiseError(__METHOD__, $message, 9111088);
                       return false;
               }
                       
               $this->_values['cardnumber'] = $cardnumber;
       
       } else if (!$this->isMerchantBinValid(
               $user_data[0]['merchantid'], $this->_values['cardnumber']))
       {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       $services = Richard_Modules_CardFunctions::init($services_options);
 
       $params  = array('cardnumber' => $this->_values['cardnumber']
                        );
 
       if ($services->getCardProfile($params)) {
           $resp_data             = $services->getResponseData();
           $values['response']    = $resp_data['profile'];
           $this->_logTransaction(__METHOD__);
           return $resp_data['profile'];
       } else {
           $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
           return false;
       }
   }
 
   /**
     * Get Card Account Balance using Services::CardFunctions
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function getCardBalance($values)
   {
       require_once "Richard/Modules/CardFunctions.php";
       require_once "Richard/Crypt/REDS.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.getbalance";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       if (isset($values['terminal_id'])) {
           $terminal_info = $this->_getTermninalInfo($values['terminal_id']);
       }
       if (!$this->isMerchantBinValid(isset($terminal_info['merchant_id'])?$terminal_info['merchant_id']:$user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
       
       
       // Check if merchant has access to the Card BIN
//        if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
//            $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
//            return false;
//        }
       
 
   }
 
   public function cashOutQuery($values)
   {
       $this->_values      =& $values;
       $transaction_type   = 1004;
       $action_code        = "mms.vas.cashout";
       $response           = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
 
       include_once "Richard/Modules/CardFunctions.php";
       include_once "Richard/System/Core.php";
       include_once "Richard/Crypt/RKMS.php";
 
       //inserted by bom 3/17/11 to base the merchant with terminal id instead of the user
       if (isset($values['terminalid'])) {
           $terminal_info = $this->_getTermninalInfo($values['terminalid']);
           $user_data[0] = array(
               'merchantid'    => $user_data[0]['merchantid'],
               'branchid'      => $terminal_info['branch_id'],
               'mmsid'         => $user_data[0]['mmsid'],
               'username'      => $user_data[0]['username'],
           );
           unset($values['terminalid']);
       }
       //end
 
       $rkms    = new Richard_Crypt_RKMS();
       $msf     = Richard_System_Core::getMSF($user_data[0]['merchantid'],$user_data[0]['branchid']);
 
       $source_card = '';
 
       if ((array_key_exists('BC',$msf)) && (!empty($msf['BC']))) {
           $source_card = $rkms->decryptByDKID($msf['BC']['cardkeyid'],$msf['BC']['cardnumber']);
       } elseif (array_key_exists('MC',$msf)) {
           $source_card = $rkms->decryptByDKID($msf['MC']['cardkeyid'],$msf['MC']['cardnumber']);
       }
 
       $cardown = Richard_System_Core::getCardOwnership($this->_values['cardnumber']);
 
       if ($user_data[0]['merchantid'] != $cardown['merchant_id']) {
           // If cross merchant loading.. then different fee scale will be used
           $transaction_type = 1005;
       } else {
           // If same merchant ownership.. then.. we just use the default fee/transaction for this
           $transaction_type = 1004;
       }
 
       $fees        = Richard_System_Core::fees($source_card);
 
       //Set the transaction amount to determine the fees
       if(isset($this->_values['trans_amount'])){
           $fees->setAmount($this->_values['trans_amount']);
       }
 
       $fee_details = $fees->getFees($transaction_type);
 
       if (count($fee_details) > 0) {
           $transaction_fee_details = $fee_details[0]['feeamount'] . " " . $fee_details[0]['feecurrency'];
           $deduct_to = $fee_details[0]['deductfrom'];
       } else {
           $transaction_fee_details = '0.00';
           $deduct_to = 'none';
       }
 
       $response = array('transactionfee' => $transaction_fee_details,
                         'transactiontype' => $transaction_type,
                         'deduct_to' => $deduct_to,
                         'merchant_id' => $user_data[0]['merchantid'],
                         'branch_id' => $user_data[0]['branchid'],
                         'mmsid' => $user_data[0]['mmsid'],
                         'process_by' => $user_data[0]['username']
                        );
 
       return $response;
   }
 
   /**
     * Account linking
     *
     * @param array $values
     */
   public function accountLinking($values)
   {
       require_once "Richard/Modules/CardFunctions.php";
       require_once "Richard/Crypt/REDS.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.linking";
       $response      = array();
 
           if ($services->getPreRegInfoByRefId($prereg_params)) {
               $resp_data = $services->getResponseData();
               $response['ref_profile']  = $resp_data['ref_profile'];
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $re) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function getPreRegInfoByRefId($values)
   {
       $this->_values      =& $values;
 
       require_once "Richard/Modules/CardFunctions.php";
 
       $action_code = "mms.cardfunctions.registration";
 
       $response    = array();
 
       // check if the user is valid
       ////$user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
      // if (!$user_data) {
          // $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
         //  return false;
       //}
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services    = Richard_Modules_CardFunctions::init($services_options);
 
           $prereg_params  = array('referencenumber' => $this->_values['referencenumber']
                               );
 
           if ($services->getPreRegInfoByRefId($prereg_params)) {
               $resp_data = $services->getResponseData();
               $response['ref_profile']  = $resp_data['ref_profile'];
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $re) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   /**
     * Save pre registered card account
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function savePreRegisteredInfo($values)
   {
       $this->_values      =& $values;
 
       require_once "Richard/Modules/CardFunctions.php";
 
       $action_code = "mms.cardfunctions.preregister";
 
       $response    = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       if (!empty($this->_values['cardnumber'])) {
           // Check if merchant has access to the Card BIN
           if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
               $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
               return false;
           }
       }
 
 
                                'homephone'            => $this->_values['homephone'],
                                'mobilephone'          => $this->_values['mobilephone'],
                                'email'                => $this->_values['email'],
                                'ssn'                  => $this->_values['ssn'],
                                'passportnumber'       => $this->_values['passportnumber'],
                                'nationalid'           => $this->_values['nationalid'],
                                'securityquestionid'   => $this->_values['securityquestionid'],
                                'securityanswer'       => $this->_values['securityanswer'],
                                'isupdate_cp'          => true
                               );
 
           // {{{ convert the mobile number PH country code to 0
           if ((isset($this->_values['mobilephone'])) && (!empty($this->_values['mobilephone']))) {
               if ((substr($this->_values['mobilephone'],0,1) == '0') && (is_numeric($this->_values['mobilephone'])) && (strlen($this->_values['mobilephone']) == 11)) {
                   $reg_params['mobilephone'] = "63" . substr($this->_values['mobilephone'],1);
               }
           }
           // }}}
 
           if ($services->registerCard($reg_params)) {
               $resp_data = $services->getResponseData();
               $response  = array('transactionid' => $resp_data['messageid']);
 
               // {{{ Add sms notice
               require_once "Richard/Modules/SMS.php";
               try {
                   $sms        = Richard_Modules_SMS::initByCard($this->_values['cardnumber']);
                   $params = array('message'       => 'Congratulations, you have successfully registered and activated your account',
                                   'mobilenumber'   => $reg_params['mobilephone'],
                                   'requestmessage' => '',
                                   'sms_id'         => 'MEGA'
                                   );
                   $sms->sendSMS($params);
               } catch (Richard_Exception $re) {
                   // do nothing.. we dont want to cancel the idea
                   // of activation even the card was already activated
               }
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $re) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function cardIDCardRegistration($values)
   {
       $this->_values      =& $values;
 
       require_once "Richard/Modules/CardFunctions.php";
       require_once "Richard/System/Core.php";
       require_once "Richard/System/Utility.php";
       require_once "Richard/Crypt/RKMS.php";
 
       $response    = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $rkms = new Richard_Crypt_RKMS();
 
       $card_info = Richard_System_Core::getCardnumberByRicaCardID($this->_values['cardid']);
 
       if ($card_info === false) {
           $this->_raiseError(__METHOD__,'Invalid Card ID',3013);
           return false;
       }
 
       $cardnumber = $card_info['cardnumber'];
       $expiration = date("m/y", strtotime($card_info['expiry']));
 
       // Check if merchant has access to the Card BIN
       if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$cardnumber)) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services    = Richard_Modules_CardFunctions::init($services_options);
 
           $username = str_replace(" ","",$this->_values['firstname']) . str_replace(" ","",$this->_values['lastname']) . Richard_System_Utility::generateID(4);
           $raw_password = Richard_System_Utility::generateID(6,'ALPHANUM');
           $password = md5($raw_password);
 
           $reg_params  = array('cardnumber'           => $cardnumber,
                                'expiration'           => $expiration,
                                'dob'                  => $this->_values['dob'],
                                'username'             => $username,
                                'password'             => $password,
                                'firstname'            => $this->_values['firstname'],
                                'middlename'           => $this->_values['middlename'],
                                'lastname'             => $this->_values['lastname'],
                                'loadamount'           => $this->_values['loadamount'],
                                'address1'             => $this->_values['address1'],
                                'address2'             => $this->_values['address2'],
                                'city'                 => $this->_values['city'],
                                'region'               => $this->_values['region'],
                                'postalcode'           => $this->_values['postalcode'],
                                'countrycode'          => $this->_values['countrycode'],
                                'homephone'            => $this->_values['homephone'],
                                'mobilephone'          => $this->_values['mobilephone'],
                                'email'                => $this->_values['email'],
                                'ssn'                  => $this->_values['ssn'],
                                'passportnumber'       => $this->_values['passportnumber'],
                                'nationalid'           => $this->_values['nationalid'],
                                'securityquestionid'   => $this->_values['securityquestionid'],
                                'securityanswer'       => $this->_values['securityanswer'],
//                                 'regstatus'            => 4, //added by bom to automatically set first login to change password screen
                                'isupdate_cp'          => true
                               );
 
           // {{{ convert the mobile number PH country code to 0
           if ((isset($this->_values['mobilephone'])) && (!empty($this->_values['mobilephone']))) {
               if ((substr($this->_values['mobilephone'],0,1) == '0') && (is_numeric($this->_values['mobilephone'])) && (strlen($this->_values['mobilephone']) == 11)) {
                   $reg_params['mobilephone'] = "63" . substr($this->_values['mobilephone'],1);
               }
           }
           // }}}
 
           if ($services->registerCard($reg_params)) {
               $resp_data = $services->getResponseData();
               $response  = array('transactionid' => $resp_data['messageid']);
 
               //added by bom for loyalty card creation/attachment
               if ($services_options['merchant_id'] == '0001') {
                   require_once "Richard/Modules/VAS/Loyalty.php";
                   $loyalty = new Richard_Modules_VAS_Loyalty($services_options);
                   $result = $loyalty->instantAddLoyalCard($cardnumber);
               }
               //end
 
               // {{{ Add sms notice
               require_once "Richard/Modules/SMS.php";
               try {
                   $sms        = Richard_Modules_SMS::initByCard($cardnumber);
                   $params = array('message'       => 'Congrats, u hav successfully registerd ur acct. Ur username is ' . $username . ' & password is ' . $raw_password . '. To activate ur acct, kindly txt ACT<space>Ur 4 DIGIT PIN & snd to 09188347328',
                                   'mobilenumber'   => $reg_params['mobilephone'],
                                   'requestmessage' => '',
//                                    'sms_id'          => 'BAYAD' //commented by bom 3/30/11 to avoid us gateway from being prioritized as sender
                                   );
                   $sms->sendSMS($params);
               } catch (Richard_Exception $re) {
                   // do nothing.. we dont want to cancel the idea
                   // of activation even the card was already activated
               }
 
               // {{{ Send Email notification
               require_once 'Mail.php';
               require_once 'Mail/mime.php';
               require_once "Richard/System/Settings.php";
               $mail_settings = Richard_System_Settings::mail('do-not-reply@bayaddirect.com');
 
               $html = "<html><body>Dear " . $this->_values['firstname'] . " " .  $this->_values['lastname'] . " <br /><br />
                        Welcome to BayadDirect!<br /><br />
                        You may access your account via SMS by texting keywords to our gateway:
                        0918 8 DIRECT or (0918 8 347328) or online by logging on to www.bayaddirect.com,
                        using your login details below:<br /><br />
                        Username: $username<br />
                        Password: $raw_password<br /><br />
 
                        Load your card at accredited BayadCenter loading stations nationwide
                        and enjoy the following convenient features online or via SMS:<br /><br />
                        <ul>
                           <li>Pay your bills</li>
                           <li>Send funds card to card</li>
                           <li>Load prepaid mobile phone for smart, globe and Sun, or be a mobile load retailer</li>
                           <li>Purchase Prepaid Load Products, game cards, phone cards and internet cards</li>
                           <li>And Many more!</li>
                        </ul>
                        <br /><br />
                        For inquiries and assistance, feel free to contact our Customer Service Representative thru:<br />
                        <blockquote>
                           SMS:  ask<space>message and send to our gateway 0918 8 DIRECT or 0918 8 347328<br />
                           Telephone Nos.: (02) 8128357, 8128359 & 8128360<br />
                           Chat: www.bayaddirect.com<br />
                           Mail: customerservice@bayaddirect.com<br />
                        </blockquote>
                        <br /><br />
                        We are more than happy to serve you!
                        <br /><br />
                        Yours truly,<br /><br />
                        Bayaddirect Team<br /><br />";
           }
       }
   }
   public function cardRegistration($values)
   {
       $this->_values      =& $values;
 
       require_once "Richard/Modules/CardFunctions.php";
 
       $action_code = "mms.cardfunctions.registration";
 
       $response    = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       //inserted by bom 3/17/11 to base the merchant with terminal id instead of the user
       if (isset($values['terminalid'])) {
           $terminal_info = $this->_getTermninalInfo($values['terminalid']);
           $user_data[0] = array(
               'merchantid'    => $terminal_info['merchant_id'],
               'branchid'      => $terminal_info['branch_id'],
               'mmsid'         => $user_data[0]['mmsid'],
               'username'      => $user_data[0]['username'],
           );
           // removed by mack, why unset terminal id, it will passed by reference on $this->_values
           //unset($values['terminalid']);
       }
       //end  
       
       if (isset($values['terminalid'])) {
           $terminal_info = $this->_getTermninalInfo($values['terminalid']);
       }
       if (!$this->isMerchantBinValid(isset($terminal_info['merchant_id'])?$terminal_info['merchant_id']:$user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
       
       
       // Check if merchant has access to the Card BIN
//        if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
//            $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
//            return false;
//        }
     
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $this->_values['platform'].'/'.$user_data[0]['username']
                                     );
           //to capture platform requestor
           $platform = $this->_values['platform'];                           
           unset($this->_values['platform']);
           //---tops 06202011
                                     
           //check merchant balance against card charge 2.99
                //by tops 041011 for tripoint
               $pos_terminal_us_demo_temp = array();
                //$pos_terminal_us_demo_temp = array("05255208","05255209","05255203","05286036");
                if(($user_data[0]['merchantid']=='92608') && (!in_array((string) $this->_values['terminalid'],$pos_terminal_us_demo_temp))){                    
                        $msf=$this->merchantBalance($services_options,$user_data[0]['merchantid'],$user_data[0]['branchid']);
                        if($msf===false){
                                        require_once "Richard/Modules/SMS.php";
                                        $card_fee_msg = "Unable to process registration. Insufficient merchant balance with terminal ID (" . $this->_values['terminalid'] . "). Please reload your account or contact tripoint.";
                                        $sms = new Richard_Modules_SMS();
                                        $params = array('message'       => $card_fee_msg,
                                                            'mobilenumber'  => $this->_values['mobilephone'],
                                                            'requestmessage'=> '',
                                                            'sms_id'            => 'bahamas',
                                                    );
                                        $sms->sendSMS($params);
                                        $this->_raiseError(__METHOD__,$card_fee_msg,$this->getErrorCode());
                                        return false;
                        }
                } else {
                    // dirty fix tsk tskts for trade show demo
                    if (isset($this->_values['terminalid'])) {
                   if (in_array((string) $this->_values['terminalid'],$pos_terminal_us_demo_temp)) {
                           $services_options['merchant_id'] = "65336";
                           $user_data[0]['merchantid'] = "65336";
                   }
                    }
                }
 
           $services    = Richard_Modules_CardFunctions::init($services_options);
           
        $reg_params  = array('cardnumber'           => $this->_values['cardnumber'],
                                'expiration'           => $this->_values['expiration'],
                                'dob'                  => $this->_values['dob'],
                                'username'             => $this->_values['username'],
                                'password'             => $this->_values['password'],
                                'firstname'            => $this->_values['firstname'],
                                'middlename'           => $this->_values['middlename'],
                                'lastname'             => $this->_values['lastname'],
                                'loadamount'           => $this->_values['loadamount'],
                                'address1'             => $this->_values['address1'],
                                'address2'             => $this->_values['address2'],
                                'city'                 => $this->_values['city'],
                                'region'               => $this->_values['region'],
                                'postalcode'           => $this->_values['postalcode'],
                                'countrycode'          => ($services_options['merchant_id'] == "65336") ? "US" : $this->_values['countrycode'],
                                'homephone'            => $this->_values['homephone'],
                                'mobilephone'          => $this->_values['mobilephone'],
                                'email'                => $this->_values['email'],
                                'ssn'                  => $this->_values['ssn'],
                                'passportnumber'       => $this->_values['passportnumber'],
                                'nationalid'           => $this->_values['nationalid'],
                                'securityquestionid'   => $this->_values['securityquestionid'],
                                'securityanswer'       => $this->_values['securityanswer'],
                                'regstatus'            => (isset($this->_values['regstatus'])) ? $this->_values['regstatus'] : '000',
                                'isupdate_cp'          => true
                               );
 
           // {{{ convert the mobile number PH country code to 0
           if ((isset($this->_values['mobilephone'])) && (!empty($this->_values['mobilephone']))) {
               if ((substr($this->_values['mobilephone'],0,1) == '0') && (is_numeric($this->_values['mobilephone'])) && (strlen($this->_values['mobilephone']) == 11)) {
                   $reg_params['mobilephone'] = "63" . substr($this->_values['mobilephone'],1);
               }
           }
           // }}}
 
           if ($services->registerCard($reg_params)) {
               $resp_data = $services->getResponseData();
               $response  = array('transactionid' => $resp_data['messageid']);
 
               //added by bom for loyalty card creation/attachment
               if ($services_options['merchant_id'] == '0001') {
                   require_once "Richard/Modules/VAS/Loyalty.php";
                   $loyalty = new Richard_Modules_VAS_Loyalty($services_options);
                   $result = $loyalty->instantAddLoyalCard($this->_values['cardnumber']);
               }
               //end
               
               //charged card fee for tripoint by tops 041011
               if($services_options['merchant_id']=='92608'){
                       $card_charged = $this->cardCharged($services_options,$msf);
               }
 
               if ($this->_values['send_sms'] !== false) {
                   // {{{ Add sms notice
                   require_once "Richard/Modules/SMS.php";
                   try {
                                                $sms_id = '';
                                                if ($user_data[0]['merchantid'] == '92608') {
                                                        $sms_id = 'bahamas';
                                                } elseif ($user_data[0]['merchantid'] == '58842') {
                                                        $sms_id = 'cayman';
                                                }
                       if($user_data[0]['merchantid']=='92608'){
                               $_msg = "Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>FirstName/LastName/4 Digit Pin.";
                       } elseif ($user_data[0]['merchantid'] == '58842') {
                           $_msg = 'Congratulations, you have successfully "Linked" your M-BUX card to your mobile phone. To complete the registration process "Reply" to this message with the following Activation command: ACT<space>FIRSTNAME/LASTNAME/4-DIGIT-PIN-CODE';
                       } elseif ($user_data[0]['merchantid']=='89195' || $user_data[0]['merchantid']=='77427' || $user_data[0]['merchantid']=='55832') {
                           if($platform=='POS'){
                               $_msg = "Congratulations, you have successfully registered your 1WorldCash account. To activate, kindly reply ACT<space>FIRSTNAME/LASTNAME/ADDRESS/4-digit PIN.";                               
                           } else {
                               $_msg = "Congratulations, you have successfully registered your 1WorldCash account. To activate, kindly reply ACT<space>4 digit PIN.";
                           }
                       } elseif($user_data[0]['merchantid'] == '94301' || $user_data[0]['merchantid'] == '17891'){
                           $_msg = "Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>Firstname<dot>Last Name<dot>PIN";
                       } else {
                           if ($services_options['merchant_id'] == "65336") {
                               $_msg = "Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>Firstname<dot>Last Name<dot>PIN";
                           } else {
                                   $_msg = "Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>4 Digit Pin.";
                           }
                       }
                       $sms        = Richard_Modules_SMS::initByCard($this->_values['cardnumber']);
                       $params = array('message'       => $_msg,
                                       'mobilenumber'   => $reg_params['mobilephone'],
                                       'requestmessage' => '',
                                       'sms_id' => $sms_id,
                                       );
                       $sms->sendSMS($params);
                   } catch (Richard_Exception $re) {
                       // do nothing.. we dont want to cancel the idea
                       // of activation even the card was already activated
                   }
               }
           } else {
               $this->_raiseError(__METHOD__,$services->getError().' register error',$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $re) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   /**
     * Check merchant balance against card charge fee
     * by tops 041011
     * @param unknown_type $sessionid
     * @param unknown_type $merchant_id
     * @param unknown_type $branch_id
     * @return array
     */
   public function merchantBalance(array $params, $merchant_id, $branch_id='0')
   {
       $fee = (float)2.99;
       if(isset($merchant_id) && isset($branch_id)){
               require_once "Richard/System/Core.php";
               require_once "Richard/Crypt/RKMS.php";
 
               $rkms = new Richard_Crypt_RKMS();               
               $msf  = Richard_System_Core::getMSF($merchant_id, $branch_id);
               $mc   = $rkms->decryptByDKID($msf['MC']['cardkeyid'], $msf['MC']['cardnumber']);
               $sc   = $rkms->decryptByDKID($msf['SC']['cardkeyid'], $msf['SC']['cardnumber']);
               $fc   = $rkms->decryptByDKID($msf['FC']['cardkeyid'], $msf['FC']['cardnumber']);
               if($branch_id!='0'){
                       $bc   = $rkms->decryptByDKID($msf['BC']['cardkeyid'], $msf['BC']['cardnumber']);
                       $bs   = $rkms->decryptByDKID($msf['BS']['cardkeyid'], $msf['BS']['cardnumber']);
                       $bf   = $rkms->decryptByDKID($msf['BF']['cardkeyid'], $msf['BF']['cardnumber']);
               }
               
               if(isset($mc) && isset($fc) && strlen($mc)==16){
                       $_services_options = array('merchant_id'       => $params['merchant_id'],
                                                  'branch_id'          => $params['branch_id'],
                                                  'platform_requestor' => 'MMS-' . $params['platform_requestor'],
                                                  'process_by'         => $params['process_by']
                                                  );
 
                        $_services = Richard_Modules_CardFunctions::init($_services_options);
                
                        $bal_params = array('cardnumber' => ($branch_id=='0')?$mc:$bc);
                
                        if ($_services->getBalance($bal_params)) {
                            $resp_data = $_services->getResponseData();
                            
                            if((float)$resp_data['availablebalance']>$fee){
                                        $msf_array = array(
                                                'MC'=>$mc,
                                                'SC'=>$sc,
                                                'FC'=>$fc,
                                                'BC'=>$bc,
                                                'BS'=>$bs,
                                                'BF'=>$bf
                                        );
                                        return $msf_array;
                                }
                        } else {
                                $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
                       return false;
                        }
               }
       }
       
       return false;
   }
   
   /**
     * Charge 2.99 card fee for every registration
     * tripoint by tops 041011
     *
     * @param unknown_type $msf
     * @return unknown
     */
   public function cardCharged(array $params, array $msf)
   {
       if(is_array($params) && is_array($msf)){
                require_once "Richard/Modules/CardFunctions.php";
                $fee        = (float)2.99;
                $to_revenue = (float)1.99;
                $to_scard   = (float)1.00;
                date_default_timezone_set("America/Nassau");
                try {
                    $services_options = array('merchant_id'        => $params['merchant_id'],
                                              'branch_id'          => $params['branch_id'],
                                              'platform_requestor' => 'MMS-' . $params['platform_requestor'],
                                              'process_by'         => $params['process_by']
                                              );
                                
                    if($params['branch_id']=='0'){
                        $from_cardnumber = $msf['MC'];
                        $to_cardnumber   = $msf['FC'];
                        $settlement_card = $msf['SC'];
                    } else {
                        $from_cardnumber = $msf['BC'];
                        $to_cardnumber   = $msf['BF'];
                        $settlement_card = $msf['BS'];
                    }
                    
                    $services   = Richard_Modules_CardFunctions::init($services_options);
        
                    $c2c_params = array('from_cardnumber'               => $from_cardnumber,
                                        'to_cardnumber'             => $to_cardnumber,
                                        'trans_amount'              => $fee,
                                        'trans_currency'            => 'BSD',
                                        'from_description'          => 'Card Registration fee Charged',
                                        'to_description'            => 'Card Registration fee Charged',
                                        'transactiontype'           => 1019//POS registration card fee
                                        );
                                
                    if ($services->cardToCardTransfer($c2c_params)) {
                        $resp_data = $services->getResponseData();
                   
                        //from fee card to settlement card 1.00                 
                        try {
                           $settlement_services = Richard_Modules_CardFunctions::init($services_options);
                           $settlement_c2c_params = array(
                                        'from_cardnumber'               => $to_cardnumber,//fee card
                                        'to_cardnumber'             => $settlement_card,
                                        'trans_amount'              => $to_scard,
                                        'trans_currency'            => 'BSD',
                                        'from_description'          => '1019 - Card Registration Charged',
                                        'to_description'            => '1019 - Card Registration Charged',
                                        'transactiontype'           => 1022//From fee to settlement card
                           );
                           if($settlement_services->cardToCardTransfer($settlement_c2c_params)){
                               $settlement_resp_data = $settlement_services->getResponseData();
                           } else {
                               $this->_raiseError(__METHOD__,$settlement_services->getError(),$settlement_services->getResponseCode());
                               return false;
                           }
                        } catch (Richard_Exception $e) {
                           $this->_raiseError(__METHOD__,$e->getMessage(),$e->getErrorCode());
                           return false;
                       }
                       
                       //from fee card to revenue card 1.99
                       $fee_services = Richard_Modules_CardFunctions::init($services_options);
                                    $fee_params = array('cardnumber'         => $to_cardnumber,
                                                'amount'                 => $to_revenue,
                                                'currency'               => 'BSD',
                                                'adjustmenttype'         => 'debit',
                                                'settlementaccounttype'  => '16',
                                                'description'            => "DEBIT FEE CARD (1019 - 1023 FEE CARD TO REVENUE)",
                                                'allownegative'          => true
                                          );
                                                      
                                    if ($fee_services->fundadjustment($fee_params)) {
                       $revenue_services = array(
                           'merchant_id'     =>$params['merchant_id'],
                           'branch_id'       =>$params['branch_id'],
                           'transaction_type'=>1019,
                           'type'            =>'credit',
                           'description'     =>'1019 - Card Registration Charged',
                           'amount'          =>$to_revenue,
                           'balance'         =>0,
                       );
                   
                       if($this->_db_rex2->insert('revenue_card', $revenue_services)){
                                    $processor_total_commision = $this->getProcessorsTotalCommision();
                               $gp = (float)$to_revenue - $processor_total_commision;
                               $merchant_revenue_cost = $this->getRevenuePerMerchant($params['merchant_id'],$params['branch_id']);
                               if((float)$merchant_revenue_cost>0 && $gp>0){
                                        $merchant_commission = $gp * ($merchant_revenue_cost/100);
                                        $debit_array = array(
                                   'merchant_id'     =>$params['merchant_id'],
                                   'branch_id'       =>$params['branch_id'],
                                   'transaction_type'=>1024,
                                   'type'            =>'debit',
                                   'description'     =>"In-Direct POS Commission ('1019 - Card Registration Charged')",
                                   'amount'          =>$merchant_commission,
                                   'balance'         =>0,
                                        );
                                        
                                        if($this->_db_rex2->insert('revenue_card', $debit_array)){
                                            $rev_services = Richard_Modules_CardFunctions::init($services_options);
                    
                                                           $rev_params = array('cardnumber'             => $settlement_card,
                                                                               'amount'                 => (float)$merchant_commission,
                                                                               'currency'               => 'BSD',
                                                                               'adjustmenttype'         => 'credit',
                                                                               'settlementaccounttype'  => '16',
                                                                               'description'            => "In-Direct POS Commission (1024 - Card Registration Charged)",
                                                                               'allownegative'          => true
                                                                         );
                                                                         
                                       if ($rev_services->fundadjustment($rev_params)){
                                           //do nothing
                                       }
                                        }
                               }
                       } else {
                               $this->_raiseError(__METHOD__,'Unable to transfer from fee card to revenue');
                              return false;
                       }
                                    }
 
                       $response = array('messageid'     => $resp_data['messageid'],
                                          'from_currency' => $resp_data['from_currency'],
                                          'to_currency'   => $resp_data['to_currency'],
                                          'trans_amount'  => $resp_data['trans_amount'],
                                          'to_amount'     => $resp_data['to_amount'],
                                          'from_amount'   => $resp_data['from_amount']
                                          );
                        return $response;             
                        
                    } else {
                        $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
                        return false;
                    }
                } catch (Richard_Exception $e) {
                    $this->_raiseError(__METHOD__,$e->getMessage(),$e->getErrorCode());
                    return false;
                }
       } else {
               $this->_raiseError(__METHOD__,'Error: Account registered. Unable to process card registration charged.');
                return false;
       }
   }
   
   public function getProcessorsTotalCommision()
   {
       $total_commission = 0;
       $processors = array(
           '0'=>array(
               'role'     =>'Processor',
               'entity'   =>'Rechargeplus Global',
               'cost_type'=>'Amount',
               'cost'     =>'0.07',
           ),
           '1'=>array(
               'role'     =>'Telecom SMS',
               'entity'   =>'Rechargeplus Bahamas',
               'cost_type'=>'Amount',
               'cost'     =>'0.03',
           ),
       );
       
       foreach ($processors as $proc){
           $total_commission += (float)$proc['cost'];
       }
       
       return $total_commission;
   }
   
   public function getRevenuePerMerchant($merchant_id,$branch_id='0')
   {
       $select = $this->_db_rex2->select()
               ->from("revenue_settings", array("revenue"))
               ->where("merchant_id=?",$merchant_id)
               ->where("branch_id=?",$branch_id);
               
       return $this->_db_rex2->fetchOne($select);
   }
   
   /**
     * Card Registration using instant issue card of
     * Services::CardFunctions (please see method details)
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function cardRegistrationByIIC($values)
   {
       $this->_values      =& $values;
 
       require_once "Richard/Modules/CardFunctions.php";
 
 
       $action_code = "mms.cardfunctions.registration";
 
       $response    = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       // Check if merchant has access to the Card BIN
       if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services    = Richard_Modules_CardFunctions::init($services_options);
 
           $reg_params  = array('cardnumber'           => $this->_values['cardnumber'],
                                'expiration'           => $this->_values['expiration'],
                                'dob'                  => $this->_values['dob'],
                                'username'             => $this->_values['username'],
                                'firstname'            => $this->_values['firstname'],
                                'middlename'           => $this->_values['middlename'],
                                'lastname'             => $this->_values['lastname'],
                                'loadamount'           => $this->_values['loadamount'],
                                'address1'             => $this->_values['address1'],
                                'address2'             => $this->_values['address2'],
                                'city'                 => $this->_values['city'],
                                'region'               => $this->_values['region'],
                                'postalcode'           => $this->_values['postalcode'],
                                'countrycode'          => $this->_values['countrycode'],
                                'homephone'            => $this->_values['homephone'],
                                'mobilephone'          => $this->_values['mobilephone'],
                                'email'                => $this->_values['email'],
                                'ssn'                  => $this->_values['ssn'],
                                'passportnumber'       => $this->_values['passportnumber'],
                                'nationalid'           => $this->_values['nationalid'],
                                'securityquestionid'   => $this->_values['securityquestionid'],
                                'securityanswer'       => $this->_values['securityanswer']
                               );
 
           if ($services->instantIssueCard($reg_params)) {
               $resp_data = $services->getResponseData();
               $response  = array('transactionid' => $resp_data['messageid']);
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $re) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function getCardLoadingFee($values)
   {
       $this->_values      =& $values;
       $transaction_type   = 1002;
       $action_code        = "mms.cardfunctions.cardloading";
       $response           = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       // Check if merchant has access to the Card BIN
       if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       include_once "Richard/Modules/CardFunctions.php";
       include_once "Richard/System/Core.php";
 
       $msf = Richard_System_Core::getMSF($user_data[0]['merchantid'],$user_data[0]['branchid']); //bom 2/20/11 corrected from branch_id to branchid
       
       $source_card = '';
 
       require_once "Richard/Crypt/RKMS.php";
 
       $rkms = new Richard_Crypt_RKMS();
 
       if ((array_key_exists('BC',$msf)) && (!empty($msf['BC']))) {
           $source_card = $rkms->decryptByDKID($msf['BC']['cardkeyid'], $msf['BC']['cardnumber']);
       } elseif (array_key_exists('MC',$msf)) {
           $source_card = $rkms->decryptByDKID($msf['MC']['cardkeyid'], $msf['MC']['cardnumber']);
       }
 
       $cardown = Richard_System_Core::getCardOwnership($this->_values['cardnumber']);
 
       if ($user_data[0]['merchantid'] != $cardown['merchant_id']) {
           // If cross merchant loading.. then different fee scale will be used
           $transaction_type = 1003;
       } else {
           // If same merchant ownership.. then.. we just use the default fee/transaction for this
           $transaction_type = 1002;
       }
 
       $fees        = Richard_System_Core::fees($source_card);
 
       $fee_details = $fees->getFees($transaction_type);
 
       if (count($fee_details) > 0) {
           $transaction_fee_details = $fee_details[0]['feeamount'] . " " . $fee_details[0]['feecurrency'];
           $deduct_to = $fee_details[0]['deductfrom'];
       } else {
           $transaction_fee_details = '0.00';
           $deduct_to = 'none';
       }
 
       $response = array('transactionfee' => $transaction_fee_details,
                         'transactiontype' => $transaction_type,
                         'deduct_to' => $deduct_to
                        );
 
       return $response;
   }
 
   /**
     * Sale Purchase
     *
     * @param unknown_type $values
     */
   public function salePurchase($values)
   {
       $this->_values      =& $values;
       $transaction_type   = 1002;
       $action_code        = "mms.vas.salepurchase";
       $response           = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       // Check if merchant has access to the Card BIN
       if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       include_once "Richard/Modules/CardFunctions.php";
       include_once "Richard/System/Core.php";
 
       $msf = Richard_System_Core::getMSF($user_data[0]['merchantid'],$user_data[0]['branchid']); //bom 2/20/11 corrected from branch_id to branchid
 
       $source_card = '';
       $target_card = $this->_values['cardnumber'];
       $source_desc = '';
       $target_desc = '';
 
       require_once "Richard/Crypt/RKMS.php";
 
       $rkms = new Richard_Crypt_RKMS();
 
       if ((array_key_exists('BC',$msf)) && (!empty($msf['BC']))) {
           $merchant_card = $rkms->decryptByDKID($msf['BC']['cardkeyid'], $msf['BC']['cardnumber']);
       } elseif (array_key_exists('MC',$msf)) {
           $merchant_card = $rkms->decryptByDKID($msf['MC']['cardkeyid'], $msf['MC']['cardnumber']);
       }
 
       $source_card = $merchant_card;
 
       $cardown = Richard_System_Core::getCardOwnership($this->_values['cardnumber']);
 
       if (strtolower($this->_values['trans_type']) == 'purchase') {
           // Set tag the transaction as purchase
           $transaction_type = 9001;
 
           // Transaction Descriptions
           $source_desc = 'PURCHASE TRANSACTION: ' . $this->_values['cardnumber'];
           $target_desc = (!empty($this->_values['trans_desc'])) ? $this->_values['trans_desc'] : 'PURCHASE TRANSACTION';
       } else {
           // Set tag the transaction as sale
           $transaction_type = 9000;
           $source_card = $this->_values['cardnumber'];
           $target_card = $merchant_card;
 
           // Transaction Descriptions
           $source_desc = (isset($this->_values['trans_desc'])) ? $this->_values['trans_desc'] : 'SALE TRANSACTION';
           $target_desc = 'SALE_TRANSACTION: ' . $this->_values['cardnumber'];
       }
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services   = Richard_Modules_CardFunctions::init($services_options);
 
           $params     = array('from_cardnumber'           => $source_card,
                               'to_cardnumber'             => $target_card,
                               'trans_amount'              => $this->_values['amount'],
                               'trans_currency'            => $this->_values['currency'],
                               'from_description'          => $source_desc,
                               'to_description'            => $target_desc,
                               'transactiontype'           => $transaction_type
                               );
 
           if ($services->cardToCardTransfer($params)) {
               $resp_data = $services->getResponseData();
               $response = array('messageid' => $resp_data['messageid'],
                                 'from_currency' => $resp_data['from_currency'],
                                 'to_currency' => $resp_data['to_currency'],
                                 'trans_amount' => $resp_data['trans_amount'],
                                 'to_amount' => $resp_data['to_amount'],
                                 'from_amount' => $resp_data['from_amount']
                                 );
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
   
   /**
     * Sale Purchase by account id
     *
     * @param unknown_type $values
     */
   public function salePurchaseByAccountId($values)
   {
       $this->_values      =& $values;
       $transaction_type   = 1002;
       $action_code        = "mms.vas.salepurchase";
       $response           = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = Richard_System_Core::getCardProfileByCard($this->_values['cardnumber']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       // Check if merchant has access to the Card BIN
       if (!$this->isMerchantBinValid($user_data['merchant_id'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       include_once "Richard/Modules/CardFunctions.php";
       include_once "Richard/System/Core.php";
 
       $msf = Richard_System_Core::getMSF($user_data['merchant_id'],$user_data['branch_id']);
 
       $source_card = $this->_values['cardnumber'];
       $target_card = '';
       $source_desc = '';
       $target_desc = '';
 
       require_once "Richard/Crypt/RKMS.php";
 
       $rkms = new Richard_Crypt_RKMS();
       $settlement_card = $rkms->decryptByDKID($msf['SC']['cardkeyid'], $msf['SC']['cardnumber']);
//        if ((array_key_exists('BC',$msf)) && (!empty($msf['BC']))) {
//            $merchant_card = $rkms->decryptByDKID($msf['BC']['cardkeyid'], $msf['BC']['cardnumber']);
//        } elseif (array_key_exists('MC',$msf)) {
//            $merchant_card = $rkms->decryptByDKID($msf['MC']['cardkeyid'], $msf['MC']['cardnumber']);
//        }
 
       $target_card = $settlement_card;
 
       $cardown = Richard_System_Core::getCardOwnership($this->_values['cardnumber']);
 
       if (strtolower($this->_values['trans_type']) == 'purchase') {
           // Set tag the transaction as purchase
           $transaction_type = 9001;
 
           // Transaction Descriptions
           $source_desc = 'PURCHASE TRANSACTION: '. $this->_values['trans_desc'];
           $target_desc = (!empty($this->_values['trans_desc'])) ? $this->_values['trans_desc'] : 'PURCHASE TRANSACTION';
       } else {
           // Set tag the transaction as sale
           $transaction_type = 9000;
           $source_card = $this->_values['cardnumber'];
           $target_card = $merchant_card;
 
           // Transaction Descriptions
           $source_desc = (isset($this->_values['trans_desc'])) ? $this->_values['trans_desc'] : 'SALE TRANSACTION';
           $target_desc = 'SALE_TRANSACTION: ' . $this->_values['cardnumber'];
       }
 
       try {
           $services_options = array('merchant_id'        => $user_data['merchant_id'],
                                     'branch_id'          => $user_data['branch_id'],
                                     'platform_requestor' => 'MMS-' . $user_data['mmsid'],
                                     'process_by'         => $user_data['username']
                                     );
 
           $services   = Richard_Modules_CardFunctions::init($services_options);
 
           $params     = array('from_cardnumber'           => $source_card,
                               'to_cardnumber'             => $target_card,
                               'trans_amount'              => $this->_values['amount'],
                               'trans_currency'            => $this->_values['currency'],
                               'from_description'          => $source_desc,
                               'to_description'            => $target_desc,
                               'transactiontype'           => $transaction_type
                               );
 
           if ($services->cardToCardTransfer($params)) {
               $resp_data = $services->getResponseData();
               $response = array('messageid' => $resp_data['messageid'],
                                 'from_currency' => $resp_data['from_currency'],
                                 'to_currency' => $resp_data['to_currency'],
                                 'trans_amount' => $resp_data['trans_amount'],
                                 'to_amount' => $resp_data['to_amount'],
                                 'from_amount' => $resp_data['from_amount']
                                 );
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),$e->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   /**
     * Sale Purchase
     *
     * @param unknown_type $values
     */
   public function SettlementTransfers($values)
   {
       $this->_values      =& $values;
       $transaction_type   = $this->_values;
       $response           = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       // Check if merchant has access to the Card BIN
       if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       include_once "Richard/Modules/CardFunctions.php";
       include_once "Richard/System/Core.php";
 
       $msf = Richard_System_Core::getMSF($user_data[0]['merchantid'],$user_data[0]['branchid']); //bom 2/20/11 corrected from branch_id to branchid
 
       $source_card = '';
       $target_card = $this->_values['cardnumber'];
       $source_desc = '';
       $target_desc = '';
 
       require_once "Richard/Crypt/RKMS.php";
 
       $rkms = new Richard_Crypt_RKMS();
 
       if ((array_key_exists('BS',$msf)) && (!empty($msf['BS']))) {
           $settlement_card = $rkms->decryptByDKID($msf['BS']['cardkeyid'], $msf['BS']['cardnumber']);
       } elseif (array_key_exists('SC',$msf)) {
           $settlement_card = $rkms->decryptByDKID($msf['SC']['cardkeyid'], $msf['SC']['cardnumber']);
       }
 
       $source_card      = $merchant_card;
 
       $cardown          = Richard_System_Core::getCardOwnership($this->_values['cardnumber']);
       $transaction_type = $this->_values['trans_code'];
 
       if ($this->_values['trans_direction'] == 'to_sc') {
           // Transaction Descriptions
           $source_desc = 'PURCHASE TRANSACTION: ' . $this->_values['cardnumber'];
           $target_desc = (isset($this->_values['trans_desc'])) ? $this->_values['trans_desc'] : 'PURCHASE TRANSACTION';
       } else {
           $source_card = $this->_values['cardnumber'];
           $target_card = $merchant_card;
 
           // Transaction Descriptions
           $source_desc = (isset($this->_values['trans_desc'])) ? $this->_values['trans_desc'] : 'SALE TRANSACTION';
           $target_desc = 'SALE_TRANSACTION: ' . $this->_values['cardnumber'];
       }
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services   = Richard_Modules_CardFunctions::init($services_options);
 
           $params     = array('from_cardnumber'           => $source_card,
                               'to_cardnumber'             => $target_card,
                               'trans_amount'              => $this->_values['amount'],
                               'trans_currency'            => $this->_values['currency'],
                               'from_description'          => $source_desc,
                               'to_description'            => $target_desc,
                               'transactiontype'           => $transaction_type
                               );
 
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services = Richard_Modules_CardFunctions::init($services_options);
 
           $params = array('cardnumber'             => $this->_values['cardnumber'],
                           'oldpin'                 => $this->_values['oldpin'],
                           'newpin'                 => $this->_values['newpin']
                          );
 
           if ($services->changeCardPin($params)) {
               $resp_data = $services->getResponseData();
               $response = array('messageid' => $resp_data['messageid']);
 
               if ((isset($this->_values['send_sms']) && ($this->_values['send_sms']))) {
                   // {{{ Add sms notice
                   require_once "Richard/Modules/SMS.php";
                   try {
                       $sms        = Richard_Modules_SMS::initByCard($this->_values['cardnumber']);
                       $sms_notice = $sms->notification();
 
                       $tpl_vars   = array('tpl_name' => 'changepin',
                                          );
 
                       $sms_notice->setTemplateValues($tpl_vars);
                       $sms_notice->processRequest();
                   } catch (Richard_Exception $re) {
                       // do nothing.. we dont want to cancel the idea
                       // of activation even the card was already activated
                   }
                   // }}}
               }
 
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   /**
     * Validate Card Account PIN
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function validateCardPIN($values)
   {
       $this->_values      =& $values;
       $response           = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
/*        // Check if merchant has access to the Card BIN
        if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
            $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
            return false;
        }
*/
 
       if (isset($values['terminal_id'])) {
           $terminal_info = $this->_getTermninalInfo($values['terminal_id']);
       }
       if (!$this->isMerchantBinValid(isset($terminal_info['merchant_id'])?$terminal_info['merchant_id']:$user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
 
       include_once "Richard/Modules/CardFunctions.php";
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'] . "=" . $this->_values['pin'],
                                     'process_by'         => (isset($this->_values['terminal_id'])) ? $this->_values['terminal_id'] : $user_data[0]['username']
//                                      'process_by'         => $user_data[0]['username']
                                     );
 
           $services = Richard_Modules_CardFunctions::init($services_options);
 
           $params = array('cardnumber'             => $this->_values['cardnumber'],
                           'pin'                    => $this->_values['pin']
                          );
 
           if ($services->verifyCardPin($params)) {
               $resp_data = $services->getResponseData();
               $response = array('messageid' => $resp_data['messageid']);
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function getCardStatus($values)
   {
       $this->_values      =& $values;
 
       $action_code = "mms.cardfunctions.cardstatus";
       $response    = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/CardFunctions.php";
       require_once "Richard/System/Core.php";
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services = Richard_Modules_CardFunctions::init($services_options);
 
           $params = array('cardnumber'         => $this->_values['cardnumber']
                          );
 
           if ($services->getCardStatus($params)) {
               $resp_data  = $services->getResponseData();
               $cardstatus = array_flip(Richard_System_Core::getCardStatus());
 
               if ($resp_data['cardstatus'] == 0) {
                   $resp_data['cardstatus'] = '000';
               }
 
               $response   = array('messageid'  => $resp_data['messageid'],
                                   'statuscode' => $resp_data['cardstatus'],
                                   'statusdesc'  => $cardstatus[$resp_data['cardstatus']]
                                  );
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function getCardStatusByCardnumber($cardnumber)
   {
       $action_code = "mms.cardfunctions.cardstatus";
       $response    = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = Richard_System_Core::getCardProfileByCard($cardnumber);
 
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Card Profile does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/CardFunctions.php";
       require_once "Richard/System/Core.php";
 
       try {
           $services_options = array('merchant_id'        => $user_data['merchant_id'],
                                     'branch_id'          => $user_data['branch_id'],
                                     'platform_requestor' => 'MMS-' . $user_data['profileid'],
                                     'process_by'         => $user_data['profile_id']
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function updateCardProfile($values)
   {
       $this->_values      =& $values;
 
       $action_code = "mms.cardfunctions.updateprofile";
 
       $response    = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       // Check if merchant has access to the Card BIN
       if ($user_data[0]['merchantid'] === '42843') {
               // if agex, no BIN check. No virtual card.
       } elseif (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/CardFunctions.php";
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services = Richard_Modules_CardFunctions::init($services_options);
 
           $params = array('cardnumber'         => $this->_values['cardnumber'],
                           'firstname'          => $this->_values['firstname'],
                           'middlename'         => $this->_values['middlename'],
                           'lastname'           => $this->_values['lastname'],
                           'suffix'             => $this->_values['suffix'],
                           'dob'                => $this->_values['dob'],
                           'address1'           => $this->_values['address1'],
                           'address2'           => $this->_values['address2'],
                           'city'               => $this->_values['city'],
                           'region'             => $this->_values['region'],
                           'postalcode'         => $this->_values['postalcode'],
                           'countrycode'        => $this->_values['countrycode'],
                           'homephone'          => $this->_values['homephone'],
                           'mobilephone'        => $this->_values['mobilephone'],
                           'email'              => $this->_values['email'],
                           'ssn'                => $this->_values['ssn'],
                           'passportnumber'     => $this->_values['passportnumber'],
                           'nationalid'         => $this->_values['nationalid'],
                           'securityquestionid' => $this->_values['securityquestionid'],
                           'securityanswer'     => $this->_values['securityanswer'],
                           'password'           => $this->_values['password'],
                           'custom'             => $this->_values['custom'],
                            'merchantid'         => $user_data[0]['merchantid']        
                  );
 
           if ($services->updateCardProfile($params)) {
               $resp_data = $services->getResponseData();
               $response = array('messageid' => $resp_data['messageid']);
 
               if ((isset($this->_values['send_sms']) && ($this->_values['send_sms']))) {
                   // {{{ Add sms notice
                   require_once "Richard/Modules/SMS.php";
                   try {
                       $sms        = Richard_Modules_SMS::initByCard($this->_values['cardnumber']);
                       $sms_notice = $sms->notification();
 
                       $tpl_vars   = array('tpl_name' => 'updateprofile',
                                          );
 
                       $sms_notice->setTemplateValues($tpl_vars);
                       $sms_notice->processRequest();
                   } catch (Richard_Exception $re) {
                       // do nothing.. we dont want to cancel the idea
                       // of activation even the card was already activated
                   }
                   // }}}
               }
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   /**
     * HELP!! (check the ECL Dataextract server in Dataone Asia)
     *
     * @param array $values
     */
   public function viewStatementMonth($values)
   {
       $this->_values      =& $values;
 
       $action_code = "mms.cardfunctions.viewstatement";
 
       $response    = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       // agex like apps. uses mobile in view search.
       $cardprofile = null;
       if ($this->_values['cardnumber'] <> 16) {
       
               require_once "Richard/System/Core.php";
               require_once "Richard/Crypt/RKMS.php";
       
               $cardprofile = Richard_System_Core::getCardProfileByMobile(
                               $this->_values['cardnumber']);
       
               if (!$cardprofile) {
                       $this->_raiseError(__METHOD__, 'Profile Mobile Number not found', 3087);
                       return false;
               }
               $rkms = new Richard_Crypt_RKMS();
       
               $cardnumber = $rkms->decryptByDKID($cardprofile['cardkeyid'],
                               $cardprofile['cardnumber']);
       
               if (!$cardnumber) {
                       $message = "Account not found!";
                       $this->_raiseError(__METHOD__, $message, 9111088);
                       return false;
               }
       
               $this->_values['cardnumber'] = $cardnumber;
       } else if (!$this->isMerchantBinValid(
               $user_data[0]['merchantid'], $this->_values['cardnumber']))
       {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/CardFunctions.php";
 
       // Get the MMS Timezone
       //$timezone = $this->getMMStz($user_data[0]['mmsid']);
       $timezone = $this->getMerchantTz($user_data[0]['merchantid']);
 
       try {
           $services_options = array('merchant_id'        => $user_data[0]['merchantid'],
                                     'branch_id'          => $user_data[0]['branchid'],
                                     'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                                     'process_by'         => $user_data[0]['username']
                                     );
 
           $services = Richard_Modules_CardFunctions::init($services_options);
 
           $params = array('cardnumber'         => $this->_values['cardnumber'],
                           'startdate'          => date("Y-m-d",mktime(0, 0, 0, date("m"), date("d")-30, date("Y"))),
                           'enddate'            => date("Y-m-d"),
                           'tz'                 => ($timezone) ? $timezone : ''
                          );
 
           if ($services->viewStatementMonth($params)) {
               $resp_data = $services->getResponseData();
               $response = array('messageid'    => $resp_data['messageid'],
                                 'timezone'     => $resp_data['timezone'],
                                 'transactions' => $resp_data['transactions'],
                                );
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),$e->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
   
   public function viewStatementCard($values) {
       $this->_values = & $values;
 
       require_once "Richard/Modules/CardFunctions.php";
 
       // Get the MMS Timezone
       $timezone = $this->getMerchantTz($this->_values['merchantid']);
 
       try {
           $services_options = array('merchant_id' => $this->_values['merchantid'],
               'branch_id' => $this->_values['branchid'],
               'platform_requestor' => 'MMS-' . $this->_values['merchantid'],
               'process_by' => 'admin'
           );
 
           $services = Richard_Modules_CardFunctions::init($services_options);
           
           $startdate = (!empty($this->_values['startdate']))?$this->_values['startdate']:date("Y-m-d", mktime(0, 0, 0, date("m"), date("d") - 30, date("Y")));
           $enddate   = (!empty($this->_values['enddate']))?$this->_values['enddate']:date("Y-m-d");
           
           $params = array(
               'cardnumber' => $this->_values['cardnumber'],
               'startdate' => $startdate,
               'enddate' => $enddate,
               'tz' => ($timezone) ? $timezone : ''
           );
 
           if ($services->viewStatementMonth($params)) {
               $resp_data = $services->getResponseData();
               $response = array('messageid' => $resp_data['messageid'],
                   'timezone' => $resp_data['timezone'],
                   'transactions' => $resp_data['transactions'],
               );
           } else {
               $this->_raiseError(__METHOD__, $services->getError(), $services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__, $e->getMessage(), $e->getErrorCode());
           return false;
       }
 
       $values['response'] = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function getMMStz($mmsid)
   {
       $stmt = $this->_db_rex2->query("SELECT timezone
                                         FROM mms
                                        WHERE id = '$mmsid'
                                        LIMIT 0, 1
                                      ");
 
       $result = $stmt->fetchAll();
 
       if (count($result) > 0) {
           return $result[0]['timezone'];
       }
 
       return false;
   }
 
   public function getMerchantTz($merchant_id)
   {
       $stmt = $this->_db_rex2->query("SELECT timezone
                                         FROM merchant
                                        WHERE merchantid = '$merchant_id'
                                        LIMIT 0, 1
                                      ");
 
       $result = $stmt->fetchAll();
 
       if (count($result) > 0) {
           return $result[0]['timezone'];
       }
 
       return false;
   }
 
   // {{{ GPS Functions
 
   public function addPayrollBatch($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.vas.payroll";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('merchant_id' => $user_data[0]['merchantid'],
                       'branch_id'   => $user_data[0]['branchid'],
                       'createdby'   => $user_data[0]['username'],
                       'title'       => $this->_values['title'],
                       'remarks'     => $this->_values['remarks'],
                       'currency'    => $this->_values['currency'],
                       'status'      => $this->_values['status'],
                       'email'       => $this->_values['email'],
                       'mobile'      => $this->_values['mobile']
                      );
 
       $result = $gps->addPayrollBatch($params);
       if (!$result) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       $response = array('payrollid' => $result['payrollid']);
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function updatePayrollBatch($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.vas.payroll";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('payrollid'   => $this->_values['payrollid'],
                       'createdby'   => $user_data[0]['username'],
                       'title'       => $this->_values['title'],
                       'remarks'     => $this->_values['remarks'],
                       'currency'    => $this->_values['currency'],
                       'merchant_id' => $user_data[0]['merchantid'],
                       'branch_id'   => $user_data[0]['branchid'],
                       'email'       => $this->_values['email'],
                       'mobile'      => $this->_values['mobile']
                      );
 
       $result = $gps->updatePayrollBatch($params);
       if (!$result) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       $response = true;
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function removePayrollBatch($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.vas.payroll";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('payrollid'   => $this->_values['payrollid'],
                       'merchant_id' => $user_data[0]['merchantid'],
                       'branch_id'   => $user_data[0]['branchid'],
                      );
 
       $result = $gps->removePayrollBatch($params);
       if (!$result) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       $response = true;
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function addPayrollDetail($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
       require_once "Richard/Validate.php";
       require_once "Richard/Crypt/RKMS.php";
 
       $this->_values =& $values;
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       // Check if merchant has access to the Card BIN
       if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
           $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
           return false;
       }
 
       $rkms = new Richard_Crypt_RKMS($this->_values['cardnumber']);
 
       $userData = Richard_Validate::isCardnumberRegistered($rkms->encrypt($this->_values['cardnumber']));
 
       if (!is_array($userData)) {
           $this->_raiseError(__METHOD__,'Card account does not exists',$userData);
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('payrollid'             => $this->_values['payrollid'],
                       'employeeid'            => (!empty($this->_values['employeeid'])) ? $this->_values['employeeid'] : '',
                       'cardid'                => $userData['cardid'],
                       'amount'                => $this->_values['amount'],
                       'udf1'                  => (!empty($this->_values['udf1'])) ? $this->_values['udf1'] : '',
                       'udf2'                  => (!empty($this->_values['udf2'])) ? $this->_values['udf2'] : '',
                       'udf3'                  => (!empty($this->_values['udf3'])) ? $this->_values['udf3'] : '',
                       'isaccountvalid'        => ($userData) ? 1 : 0,
                       'isaccountvalidmessage' => ($userData) ? "Validated" : "Card account does not exists",
                       'merchant_id'           => $user_data[0]['merchantid'],
                       'branch_id'             => $user_data[0]['branchid']
                      );
 
       $result = $gps->addPayrollDetail($params);
       if (!$result) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       $values['response']    = $result;
       $this->_logTransaction(__METHOD__);
 
       return $result;
   }
 
   public function getPayrollDetailInfo($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.vas.payroll";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('detailid'              => $this->_values['detailid'],
                       'payrollid'             => $this->_values['payrollid'],
                       'merchant_id'           => $user_data[0]['merchantid'],
                       'branch_id'             => $user_data[0]['branchid']
                      );
 
       $result = $gps->getPayrollDetailInfo($params);
 
       if (!$result) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('merchant_id' => $user_data[0]['merchantid'],
                       'branch_id'   => $user_data[0]['branchid']);
 
       $result = $gps->getPayrollBatchesByMerchant($params);
 
       if ($result === false) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       return $result;
   }
 
   public function getPayrollBatchInfoByMerchant($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.vas.payroll";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('merchant_id' => $user_data[0]['merchantid'],
                       'branch_id'   => $user_data[0]['branchid'],
                       'payrollid'   => $this->_values['payrollid']
                       );
 
       $result = $gps->getPayrollBatchInfoByMerchant($params);
 
       if (!$result) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       return $result;
   }
 
   public function executePayroll($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
 
       $this->_values =& $values;
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('merchant_id' => $user_data[0]['merchantid'],
                       'branch_id'   => $user_data[0]['branchid'],
                       'payrollid'   => $this->_values['payrollid']
                       );
 
       $result = $gps->executePayroll($params);
 
       if ($result === false) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       $values['response']    = $result;
       $this->_logTransaction(__METHOD__);
 
       return $result;
   }
 
   public function activatePayroll($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
 
       $this->_values =& $values;
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('merchant_id' => $user_data[0]['merchantid'],
                       'branch_id'   => $user_data[0]['branchid'],
                       'payrollid'   => $this->_values['payrollid']
                       );
 
       $result = $gps->activatePayroll($params);
 
       if ($result === false) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       $values['response']    = $result;
       $this->_logTransaction(__METHOD__);
 
       return $result;
   }
 
   public function getProcessedPayroll($values = array())
   {
       require_once "Richard/Modules/VAS/GPS.php";
 
       $this->_values =& $values;
 
       $action_code   = "mms.vas.payroll";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
 
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $gps    = new Richard_Modules_VAS_GPS();
 
       $params = array('merchant_id' => $user_data[0]['merchantid'],
                       'branch_id'   => $user_data[0]['branchid'],
                       'payrollid'   => $this->_values['payrollid']
                       );
 
       $result = $gps->getProcessedPayroll($params);
 
       if ($result === false) {
           $this->_raiseError(__METHOD__,$gps->getError(),$gps->getErrorCode());
           return false;
       }
 
       return $result;
   }
 
   // }}}
 
   /**
     * Get MMS User Session Information
     *
     * @access private
     * @param  string $sessionid
     * @return mixed
     */
   public function _getMerchantSessionInfo($sessionid)
   {
       require_once "Richard/Services/SessionHandler.php";
 
       $sess      = new Services_SessionHandler();
       $user_info = $sess->decryptSessionID($sessionid);
       $user_id   = $user_info[2];
       $mms       = new Richard_Modules_MMS();
       $user_data = $mms->getMerchantUserInfo($user_id);
       if (count($user_data) > 0) {
           return $user_data;
       } else {
           $this->_error     = 'Requesting User ID does not exists';
           $this->_errorcode = 3009;
           return false;
       }
   }
 
   /**
     * (Public Alias) Get MMS User Session Information
     *
     * @access public
     * @param  string $sessionid
     * @return mixed
     */
   public function getMerchantSessionInfo($sessionid)
   {
       return $this->_getMerchantSessionInfo($sessionid);
   }
       $this->_values_data = &$values['data'];
       
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
               $this->_raiseError(__METHOD__, 'Merhchant user does not exist', $this->getErrorCode());
               return false;
       }
               
       $cardprofile = $this->_values_data;
       
       if (isset($this->_values['profileid']) &&
               !empty($this->_values['profileid']))
       {
               /*
                 * for profiles without a card account
                 */
                $cardprofile = Richard_System_Core::getCardProfileByProfileID(
                        $this->_values['profileid']);
       
                if (!$cardprofile) {
                        $this->_raiseError(__METHOD__, 'Account Profile does not exist!', 9110056);
                        return false;
                }
       
           if($cardprofile['regstatus'] == 1) {
               $this->_raiseError(__METHOD__, 'Profile already has a card account!', 9110056);
               return false;
           }
       } else {
               /*
                 * For MMS initiated registrations
                 */
               $profileid = 0;
               
               try {
                       $transactionid = Richard_System_Utility::uniqueTimestamp();
                       
                       $mobile_exists = Richard_Validate::isMobileExist($cardprofile['mobilephone']);
                        if ($mobile_exists === 1003) {
                                $this->_raiseError(__METHOD__, 'Mobile number exists!', $mobile_exists);
                                return false;
                        }
                       
                       $this->_db_rex2->beginTransaction();
                       
                        $sql_cp = "INSERT INTO cardprofiles
                                   SET firstname = '{$cardprofile['firstname']}',
                                         city = '{$cardprofile['city']}',
                                         lastname = '{$cardprofile['lastname']}',
                                         address1 = '{$cardprofile['address1']}',
                                         countrycode = '{$cardprofile['countrycode']}',
                                         mobilephone = '{$cardprofile['mobilephone']}',
                                         passportnumber = '{$cardprofile['passportnumber']}',
                                         merchant_id = '{$user_data[0]['merchantid']}',
                                         branch_id = '{$user_data[0]['branchid']}',
                                         process_by = '{$user_data[0]['username']}',
                                         transactionid = '{$transactionid}',
                                         platform_requestor = 'MMS',
                                         dob = '{$cardprofile['dob']}'";
                        
                        $this->_db_rex2->query($sql_cp);
                        $profileid = $this->_db_rex2->lastInsertId();
                        
                        if (!$profileid) {
                                $this->_raiseError(__METHOD__, 'Failed to register profile!', 911008);
                                return false;
                        }
                        
                        $sql_cn = "INSERT into cardprofiles_cardnumber
                                         SET cardprofileid = '{$profileid}',
                                                cardnumber = '{$profileid}',
                                                cardtype = 'CA',
                                                regstatus = 0,
                                                isprimaryaccount = 1";
                        
                        $this->_db_rex2->query($sql_cn);
                        $card_id = $this->_db_rex2->lastInsertId();
                        
                        if (!$card_id) {
                                $this->_raiseError(__METHOD__, 'Failed to create account profile!', 911008);
                                return false;
                        }
               } catch (Exception $e) {
                       $this->_db_rex2->rollback();
                       $this->_raiseError(__METHOD__, $e->getMessage(), $e->getCode());
                       return false;
               }
               
               $this->_db_rex2->commit();
               
               // init fields to be used later
               $cardprofile['profileid'] = $profileid;
               $cardprofile['ssn'] = '';
               $cardprofile['address2'] = '';
               $cardprofile['city'] = '';
               $cardprofile['postalcode'] = '';
               $cardprofile['homephone'] = '';
               $cardprofile['email'] = '';
               
       
                               $encrypt_cardnumber = $rkms->encrypt($gencard['CardNumber']);
                               $maskedcardnumber = Richard_System_Utility::maskCardnumber($gencard['CardNumber']);
                               $address1 = $rkms->encrypt($cardprofile['address1']);
                               $dob = $rkms->encrypt($cardprofile['dob']);
                               $expiration_date = $rkms->encrypt($expiration_date);
        
                               $account_number = Richard_System_Core::getAccountNumberByCardnumber($gencard['CardNumber']);
                               if (!$account_number)
                                       $account_number = "";
       
                               $sql1 = "UPDATE cardprofiles_cardnumber
                                                  SET cardaccountnumber = '{$account_number}',
                                                          cardnumber = '{$encrypt_cardnumber}',
                                                          expiration = '{$expiration_date}',
                                                          cardkeyid = '" . $dk_info['dk_id'] . "',
                                                          regstatus = 1
                                                WHERE cardprofileid = {$cardprofile['profileid']}";
       
                               $this->_db_rex2->query($sql1);
       
                               $sql2 = "INSERT INTO cardprofiles_pin
                                                 SET pin = '" . Richard_System_Utility::generateHash('0000') . "',
                                                         profile_id = {$cardprofile['profileid']}";
       
                               $this->_db_rex2->query($sql2);
                               
                               $sql3 = "UPDATE cardprofiles
                                                  SET address1 = '{$address1}',
                                                          dob = '{$dob}'
                                                WHERE id = {$cardprofile['profileid']}";
                                                
                               $this->_db_rex2->query($sql3);
                       }
               } else {
                       $this->_raiseError(__METHOD__, $client_createcard->getError(),
                               $client_createcard->getResponseCode());
                       return false;
               }
       } catch (Exception $e) {
               $this->_raiseError(__METHOD__, $e->getMessage(), $e->getCode());
               return false;
       }
       
       return true;
   }
 
   /**
     * Create Pre Reg Account
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function createPreRegAccount($values)
   {
       $this->_values      =& $values;
 
       require_once "Richard/Modules/CardFunctions.php";
 
       $action_code = "mms.cardfunctions.preregister";
 
       $response    = array();
 
       if (!empty($this->_values['cardnumber'])) {
           // Check if merchant has access to the Card BIN
           if (!$this->isMerchantBinValid($user_data[0]['merchantid'],$this->_values['cardnumber'])) {
               $this->_raiseError(__METHOD__,$this->getError(),$this->getErrorCode());
               return false;
           }
       }
 
       try {
           $services_options = array('merchant_id'        => $this->_values['merchantid'],
                                     'branch_id'          => $this->_values['branchid'],
                                     'platform_requestor' => (isset($this->_values['platform_requestor'])) ? $this->_values['platform_requestor'] : 'MMS-' . $this->_values['mmsid'],
                                     'process_by'         => $this->_values['username']
                                     );
 
           $services = Richard_Modules_CardFunctions::init($services_options);
 
           $preg_params = array('cardnumber'           => $this->_values['cardnumber'],
                                'dob'                  => $this->_values['dob'],
                                'username'             => $this->_values['username'],
                                'password'             => $this->_values['password'],
                                'firstname'            => $this->_values['firstname'],
                                'middlename'           => $this->_values['middlename'],
                                'lastname'             => $this->_values['lastname'],
                                'address1'             => $this->_values['address1'],
                                'address2'             => $this->_values['address2'],
                                'city'                 => $this->_values['city'],
                                'region'               => $this->_values['region'],
                                'postalcode'           => $this->_values['postalcode'],
                                'countrycode'          => $this->_values['countrycode'],
                                'homephone'            => $this->_values['homephone'],
                                'mobilephone'          => $this->_values['mobilephone'],
                                'email'                => $this->_values['email'],
                                'ssn'                  => $this->_values['ssn'],
                                'passportnumber'       => $this->_values['passportnumber'],
                                'nationalid'           => $this->_values['nationalid'],
                                'securityquestionid'   => $this->_values['securityquestionid'],
                                'securityanswer'       => $this->_values['securityanswer'],
                                'custom'                       => $this->_values_data['custom']
                               );
 
           if ($services->preRegister($preg_params)) {
               $resp_data = $services->getResponseData();
               $response = array('referencenumber' => $resp_data['referencenumber']);
 
               if ((isset($this->_values['send_sms']) && ($this->_values['send_sms']))) {
                   // {{{ Add sms notice
                   require_once "Richard/Modules/SMS.php";
                   try {
                       $sms          = Richard_Modules_SMS::initByMobile($this->_values['mobilephone']);
 
                       // we need to override the validation if the mobile or cardnumber exists for this profile
                       // since this is only pre-reg, there is no set profile...
                       $sms->profile = array_merge($this->_values,$services_options);
                       $sms_notice   = $sms->notification();
 
                       $tpl_vars     = array('tpl_name' => 'cardprereg',
                                             'tpl_vars' => array('REFID'   => $resp_data['referencenumber']
                                                               )
                                            );
 
                       $sms_notice->setTemplateValues($tpl_vars);
                       $sms_notice->processRequest();
                   } catch (Richard_Exception $re) {
                       // do nothing.. we dont want to cancel the idea
                       // of activation even the card was already activated
                   }
                   // }}}
               }
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $re) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function registerByCardID($values)
   {
       $this->_values      =& $values;
 
       require_once "Richard/Modules/CardFunctions.php";
       require_once "Richard/Crypt/REDS.php";
 
       $action_code = "mms.cardfunctions.registration";
 
       $response    = array();
 
       $card_info = Richard_System_Core::getCardinfoByAccountID($this->_values['cardid']);
       $expiration = Richard_Crypt_REDS::cardinfo($card_info['expiration'],'DECRYPT');
       $exp_arr = explode("/", $expiration);
       $exp = $exp_arr[0] . "/" . substr($exp_arr[2],-2);
 
       try {
           $services_options = array('merchant_id'        => $this->_values['merchantid'],
                                     'branch_id'          => $this->_values['branchid'],
                                     'platform_requestor' => (isset($this->_values['platform_requestor'])) ? $this->_values['platform_requestor'] : 'MMS-' . $this->_values['mmsid'],
                                     'process_by'         => $this->_values['username']
                                     );
 
           $services    = Richard_Modules_CardFunctions::init($services_options);
 
           $reg_params  = array('cardnumber'           => Richard_Crypt_REDS::cardinfo($card_info['cardnumber'],'DECRYPT'),
                                'expiration'           => $exp,
                                'dob'                  => $this->_values['dob'],
                                'username'             => $this->_values['username'],
                                'password'             => $this->_values['password'],
                                'firstname'            => $this->_values['firstname'],
                                'middlename'           => $this->_values['middlename'],
                                'suffix'               => isset($this->_values['suffix'])? $this->_values['suffix']: '',
                                'lastname'             => $this->_values['lastname'],
                                'loadamount'           => $this->_values['loadamount'],
                                'address1'             => $this->_values['address1'],
                                'address2'             => $this->_values['address2'],
                                'city'                 => $this->_values['city'],
                                'region'               => $this->_values['region'],
                                'postalcode'           => $this->_values['postalcode'],
                                'countrycode'          => $this->_values['countrycode'],
                                'homephone'            => $this->_values['homephone'],
                                'mobilephone'          => $this->_values['mobilephone'],
                                'email'                => $this->_values['email'],
                                'ssn'                  => $this->_values['ssn'],
                                'passportnumber'       => $this->_values['passportnumber'],
                                'nationalid'           => $this->_values['nationalid'],
                                'securityquestionid'   => $this->_values['securityquestionid'],
                                'securityanswer'       => $this->_values['securityanswer'],
                                'isupdate_cp'          => true
                               );
 
           if ($services->registerCard($reg_params)) {
               $resp_data = $services->getResponseData();
               $response  = array('transactionid' => $resp_data['messageid'],
                                  'profileid'     => $resp_data['profileid']
                                  );
 
               if ((isset($this->_values['send_sms']) && ($this->_values['send_sms']))) {
                   // {{{ Add sms notice
                   require_once "Richard/Modules/SMS.php";
                   try {
                       $sms          = Richard_Modules_SMS::initByMobile($this->_values['mobilephone']);
 
                       // we need to override the validation if the mobile or cardnumber exists for this profile
                       // since this is only the first reg, there is no profile set...
                       $sms->profile = array_merge($this->_values,$services_options);
                       $sms_notice   = $sms->notification();
 
                       $tpl_vars     = array('tpl_name' => 'cardreg'
                                            );
 
                       $sms_notice->setTemplateValues($tpl_vars);
                       $sms_notice->processRequest();
                   } catch (Richard_Exception $re) {
                       // do nothing.. we dont want to cancel the idea
                       // of activation even the card was already activated
                   }
                   // }}}
               }
           } else {
               $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $re) {
           $this->_raiseError(__METHOD__,$re->getMessage(),$re->getErrorCode());
           return false;
       }
 
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function getBIN($currency)
   {
       require_once "Richard/Db.php";
 
       $db      = new Richard_Db();
       $db_rex2 = $db->connect('REX2_CARDPRODUCTION');
 
                $this->_values      =& $values;
 
                $stmt = $db_rex2->query("SELECT *
                                           FROM cardproduction_bin
                                          WHERE Currency = '" . strtoupper($currency) . "' AND
                                                        Type = 'CA'
                                          LIMIT 0, 1");
                $result = $stmt->fetchAll();
                if (count($result) > 0) {
               return $result[0]['BIN'] . $result[0]['BINEXT'];
                }
 
                return;
   }
 
 
   /**
     * Get Card Merchant Cardholders' Profile
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function getMerchantCardholders($values)
   {
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.getmerchantcardholders";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $status_cond = '';
       if ($this->_values['status'] !== null) {
           $status_cond = "AND cp_cn.regstatus = " . $this->_values['status'];
       }
       $actions_stmt = "SELECT CONCAT(TRIM(cp.firstname), ' ', TRIM(cp.lastname)) AS cardholder_name,
                               cp.address1,cp_cn.cardkeyid, cp.city, cp.countrycode, cp.mobilephone, cp.datecreated, cp.id as card_id
                          FROM cardprofiles as cp,cardprofiles_cardnumber as cp_cn
                         WHERE cp.merchant_id  = " . $this->_values['merchantid'] . "
                           AND cp_cn.cardtype  = 'CA'
                           AND cp.id           = cp_cn.cardprofileid ".
                           $status_cond;
 
       $stmt         = $this->_db_rex2->query($actions_stmt);
       $profiles_res = $stmt->fetchAll();
       $resp_data = array('total_records' => count($profiles_res),
                          'cardholders'   => $profiles_res,
                          );
 
       $values['response']    = $resp_data;
       $this->_logTransaction(__METHOD__);
       return $resp_data;
   }
 
   /**
     * Search OWN cardholders matching specified firstname, lastname or mobile number
     *
     * @param array $values array containing search filters
     * @return bool|array return false upon error, array of matching profiles if matched
     * @author Emmanuel A. Lim (Bom)
     * @copyright 2/3/2010 Rechargeplus
     * @todo Implement checking that only KSK-based user can access this function
     * @todo Implement Exception handling, error and transaction logging
     */
   public function searchOwnCardholders($values) {
       $errPrefix = '10121';
       $this->_values = &$values;
       $merchantId = '61298';
 
       /**
         * validates sessionid; validates search paramters
         */
       if (!$this->_getMerchantSessionInfo($values['sessionid'])) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       } elseif (!isset($values['firstname'], $values['lastname'], $values['mobile'])) {
           $this->_raiseError(__METHOD__, 'Incomplete parameters', $errPrefix . 2); //todo: create a proper error code
           return false;
       } else {
           /**
             * Valid session and parameter, create db query for matching
             */
           $val[] = 'CA'; //Filter result for card account only
           $val[] = $merchantId; //todo: replace with actual ksk merchant id
           if (isset($values['firstname']) && trim($values['firstname']) != '') {
               $where[] = 'firstname=?';
               $val[] = $values['firstname'];
           }
           if (isset($values['lastname']) && trim($values['lastname']) != '' ) {
               $where[] = 'lastname=?';
               $val[] = $values['lastname'];
           }
           if (isset($values['mobile']) && trim($values['mobile']) != '') {
               $where[] = 'mobilephone=?';
               $val[] = $values['mobile'];
           }
           $query = '
               SELECT  cardprofiles.id as profileid, firstname, lastname, dob, mobilephone as mobile, address1, cardkeyid, city
               FROM    cardprofiles,cardprofiles_cardnumber
               WHERE   cardprofiles_cardnumber.cardprofileid=cardprofiles.id
                AND    cardprofiles_cardnumber.cardtype=?
                AND    merchant_id=?
                AND    (' . implode(' OR ', $where) . ')';
           try {
               $result = $this->_db_rex2->fetchAll($query, $val);
               /**
                 * return record count and cardholder's profile matched
                 */
               return array('total_records' => count($result), 'result' => $result);
           } catch (Exception $e) {
               $this->_raiseError(__METHOD__, 'Database query error', $errPrefix . 3); //todo: create a proper error code
               return false;
           }
       }
   }
 
   /**
     * Utility to get MSF based on merchant ID and the type of card, decrypts the cardnumber before returning
     *
     * @param string $merchant_id 5-digit merchant id
     * @param string $type 2-character code to identify the type of card (e.g. SC, FC, etc.)
     * @return string|bool
     */
   private function _getMerchantCard($merchant_id, $type) {
       if (strlen(trim($merchant_id)) == 5 && strlen($type) == 2) {
           $msf = Richard_System_Core::getMSF($merchant_id, 0);
           if (count($msf) > 0 && isset($msf[$type])) {
               $rkms = new Richard_Crypt_RKMS();
               $decrypted = $rkms->decryptByDKID($msf[$type]['cardkeyid'], $msf[$type]['cardnumber']);
               if (strlen($decrypted) == 16) {
                   return $decrypted;
               }
           }
       }
       return false;
   }
 
   /**
     * Execute payout (c2c) from KSK merchant to cardholder/ksk member
     *
     * @param array $values array containing sessionid, payout amount, profileid of member, and requesting ksk staff id as process by
     * @return bool|array return false upon error, array of matching profiles if matched
     * @author Emmanuel A. Lim (Bom)
     * @copyright 2/7/2010 Rechargeplus
     * @todo Implement checking that only KSK-based user can access this function
     * @todo Implement Exception handling, error and transaction logging
     */
 
   public function payoutKSKmember($values) {
       $errPrefix = '1010';
       $forTesting = false;
       $this->_values = & $values;
       $merchantId = '87089'; //todo: replace with actual
       $transactionType = 5506; //replace with actual
       /**
         * validates sessionid; validates payout paramters
         */
       if (!$this->_getMerchantSessionInfo($this->_values['sessionid'])) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       } elseif (!isset($values['profile'], $values['amount'], $values['processby'])) {
           $this->_raiseError(__METHOD__, 'Incomplete parameters', $errPrefix . 12);
           return false;
       } elseif (trim($values['processby']) == '') { //todo: correct messages
           $this->_raiseError(__METHOD__, 'Invalid process by', $errPrefix . 13);
           return false;
       } elseif (!(is_numeric($values['profile']) && trim($values['profile']) > 0)) {
           $this->_raiseError(__METHOD__, 'Invalid profile ID', $errPrefix . 14);
           return false;
       } elseif (!(is_numeric($values['amount']) && trim($values['amount'] > 0))) {
           $this->_raiseError(__METHOD__, 'Invalid payout amount', $errPrefix . 15);
           return false;
       } else {
           require_once "Richard/Modules/CardFunctions.php";
           require_once "Richard/System/Core.php";
           require_once "Richard/Crypt/RKMS.php";
           $to_cn = Richard_System_Core::GetCardnumberByProfileID($values['profile']);
           if (!$to_cn) {
               return $this->raiseError("Unable to get member cardnumber", $errPrefix . 16);
           }
           $rkms = new Richard_Crypt_RKMS();
           $to_cn = $rkms->decryptByDKID($to_cn['cardkeyid'], trim($to_cn['cardnumber']));
           $from_cn = $this->_getMerchantCard($merchantId, 'MC');
           $services_options = array(
               'merchant_id'        => $merchantId,
               'branch_id'          => '0',
               'platform_requestor' => 'KSK',
               'process_by'         => $values['processby'],
           );
           $service = Richard_Modules_CardFunctions::init($services_options);
           $params = array(
               'from_cardnumber'   => $from_cn,
               'to_cardnumber'     => $to_cn,
               'trans_amount'      => $values['amount'],
               'from_description'  => 'KSK PAYOUT TO ' . Richard_System_Utility::maskCardnumber($to_cn),
               'to_description'    => 'KSK INVESTMENT PAYOUT',
               'transactiontype'   => $transactionType // todo: check and correct ksk payout transaction
           );
           if ($forTesting || $service->cardToCardTransfer($params)) {
               if ($forTesting) {
                   $response['messageid'] = 123123213;
               } else {
                   $response = $service->getResponseData();
               }
               $resp_data = array(
                   'result'    => true,
                   'messageid' => $response['messageid'],
               );
           } else {
               $this->_raiseError(__METHOD__, 'Unable to perform cardtocardtransfer', $service->getResponseCode());
               return false;
           }
       }
       $values['response'] = $resp_data;
       $this->_logTransaction(__METHOD__);
       return $values['response'];
   }
 
 
   /**
     * Get All Merchants with details of cardholder count
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function getMerchantListWithCardholderCount($values)
   {
       if (isset($values['mode']) && $values['mode'] == 'mobile') {
           $add = " AND cp.mobilephone is not null AND TRIM(cp.mobilephone) <> ''";
       } elseif (isset($values['mode']) && $values['mode'] == 'email') {
           $add = " AND cp.email is not null AND TRIM(cp.email) <> ''";
       } else {
           $add = '';
       }
 
       $actions_stmt = "SELECT m.merchantid, CONCAT(m.name, ' (', count( * ), ')')
                       FROM merchant AS m, cardprofiles AS cp, cardprofiles_cardnumber AS cp_cn
                       WHERE cp_cn.cardtype = 'CA'
                       AND cp.id = cp_cn.cardprofileid
                       AND cp.merchant_id = m.merchantid".
                       $add .
                       " GROUP BY m.name, m.merchantid";
       $merchant_list = $this->_db_rex2->fetchPairs($actions_stmt);
       $resp_data = array(
                          'merchant_list'   => $merchant_list,
                          );
       return $resp_data;
   }
 
   /**
     * Get All Merchant's Cardholder's Mobile/Email
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function getMerchantsCardholdersContact($values)
   {
       if (isset($values['merchants']) && count($values['merchants']) > 0) {
           $merchant_list = implode("','", $values['merchants']);
           if (isset($values['mode']) && $values['mode'] == 'mobile') {
               $select = "cp.mobilephone, CONCAT(cp.firstname,' ',cp.lastname) as name";
               $add = " AND cp.mobilephone is not null AND TRIM(cp.mobilephone) <> ''";
           } elseif (isset($values['mode']) && $values['mode'] == 'email') {
               $select = "cp.email, CONCAT(cp.firstname,' ',cp.lastname) as name";
               $add = " AND cp.email is not null AND TRIM(cp.email) <> ''";
           } else {
               return false;
           }
       } else {
           return false;
       }
 
       $actions_stmt = "SELECT {$select}
                       FROM cardprofiles AS cp, cardprofiles_cardnumber AS cp_cn
                       WHERE cp.id = cp_cn.cardprofileid
                       AND cp_cn.cardtype = 'CA'
                       AND cp.merchant_id IN ('{$merchant_list}')".
                       $add;
 
       $contacts_list = $this->_db_rex2->fetchPairs($actions_stmt);
       $resp_data = array(
                          'contacts_list'   => $contacts_list,
                          );
       return $resp_data;
   }
   /**
     * Send email messages
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function notifierSendEmail($values)
   {
       if ((isset($values['additional']) && strlen($values['additional']) > 0) || (isset($values['contacts']) && count($values['contacts']) > 0)) {
           if (isset($values['contacts']) && count($values['contacts']) > 0) {
               $orig_recipients = implode(',', array_keys($values['contacts']));
           } else {
               $orig_recipients = null;
           }
 
           $additional_recipients = isset($values['additional']) && strlen($values['additional']) > 1? trim($values['additional'], ' ,'): null;
           $all_recipients = explode(',', trim($additional_recipients . ',' . $orig_recipients, ' ,'));
           $sent = 0;
           foreach ($all_recipients as $email) {
               if (preg_match('/^((\"[^\"\f\n\r\t\v\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/D', $email)) {
                   $sent++;
               }
           }
           if ($sent > 0) {
               $to = 'advisory@rechargeplus.com';
               $recipients = implode(',', $all_recipients); //todo: enable when deploying
               //todo: disable when deploying
               //$recipients = 'emmanuel.lim@rechargeplus.com,debi.santos@rechargeplus.com';
 
               $headers  = 'MIME-Version: 1.0' . "\r\n";
               $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
               $headers .= 'To: Advisory <' . $values['from'] . ">\r\n";
               $headers .= 'From: Advisory <' . $values['from'] . ">\r\n";
               $headers .= 'Bcc: ' . $recipients . "\r\n";
 
               //todo: disable
               //$values['subject'] .= implode(',', $all_recipients);
 
               mail('', $values['subject'], $values['message'], $headers);
 
               $data = array(
                   'sender'    => $values['sender'],
                   'from'      => $values['from'],
                   'subject'   => $values['subject'],
                   'merchants' => isset($values['merchant_list'])? implode(',', $values['merchant_list']): null,
                   'additional'=> $values['additional'],
                   'total'     => $sent,
                   'message'   => base64_encode($values['message']),
                   'remarks'   => (count($all_recipients) - $sent)>0?(count($all_recipients) - $sent) . ' recipients not sent, either because of invalid email address, or duplicate entry':null,
                   );
               $result = $this->_db_rex2->insert('logs_rex2_notifier', $data);
               //todo: check limit of bcc field and rewrite code if needed;
               return true;
           } else {
               return false;
           }
       } else {
           return false;
       }
   }
   /**
     * Send SMS messages
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function notifierSendSMS($values)
   {
       $api_url = 'http://rexgateway.com/smsc/sendsms_new.php?user=rplus&mobile=';
       if ((isset($values['additional']) && strlen($values['additional']) > 0) || (isset($values['contacts']) && count($values['contacts']) > 0)) {
           if (isset($values['contacts']) && count($values['contacts']) > 0) {
               $orig_recipients = implode(',', array_keys($values['contacts']));
           } else {
               $orig_recipients = null;
           }
           $additional_recipients = isset($values['additional']) && strlen($values['additional']) > 1? trim($values['additional'], ' ,'): null;
           $all_recipients = explode(',', trim($additional_recipients . ',' . $orig_recipients, ' ,'));
           $sent = 0;
           foreach ($all_recipients as $mobile) {
               $mobile = trim($mobile, ' +');
               if (is_numeric($mobile) && strlen($mobile) > 10) {
                   $sent++;
               }
           }
           if ($sent > 0) {
               require_once "Richard/Modules/SMS.php";
               $sms = new Richard_Modules_SMS();
               set_time_limit(0);
               foreach ($all_recipients as $mobile) {
                   $mobile = trim($mobile, ' +');
                   if (is_numeric($mobile) && strlen($mobile) > 10) {
                       $sms_params = array(
                           'message'      => $values['message'],
                           'mobilenumber' => $mobile,
                           'addfee'       => false,
                       );
                       $sms->sendSMS($sms_params);
//                        file_get_contents($api_url . $mobile . '&message=' . urlencode(stripslashes($values['message']))); //todo: enable when deploying
//                        sleep(5);
                   }
               }
               //todo: disable when deploying
//                file_get_contents($api_url . '09102620595&message=' . implode(',', $all_recipients) . $values['message']);
//                file_get_contents($api_url . '09285068023&message=' . implode(',', $all_recipients) . $values['message']);
 
               $data = array(
                   'sender'    => $values['sender'],
                   'from'      => 'sms',
                   'merchants' => isset($values['merchant_list'])? implode(',', $values['merchant_list']): null,
                   'additional'=> $values['additional'],
                   'total'     => $sent,
                   'message'   => base64_encode($values['message']),
                   'remarks'   => (count($all_recipients) - $sent)>0?(count($all_recipients) - $sent) . ' recipients not sent, either because of invalid mobile number, or duplicate entry':null,
                   );
               $result = $this->_db_rex2->insert('logs_rex2_notifier', $data);
               return true;
           } else {
               return false;
           }
       } else {
           return false;
       }
   }
 
   /**
     * Get Notifier Logs
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function NotifierGetLogs($values)
   {
       if (isset($values['mode']) && $values['mode'] == 'mobile') {
           $where = "`from` = 'sms'";
       } elseif (isset($values['mode']) && $values['mode'] == 'email') {
           $where = "`from` <> 'sms'";
       } else {
           return false;
       }
       if (isset($values['user']) && $values['user'] !== null) {
           $where .= " AND `sender`='{$values['user']}'";
       }
 
       if (isset($values['id']) && $values['id'] != null && $values['id'] > 0) {
           $where .= " AND id = {$values['id']}";
       }
 
       $actions_stmt = "SELECT *
                       FROM logs_rex2_notifier
                       WHERE $where
                       ORDER BY date_sent DESC";
 
       $logs = $this->_db_rex2->fetchAll($actions_stmt);
       $resp_data = array('logs' => $logs);
       return $resp_data;
   }
 
   public function notifierProcessUser($values) {
       if (isset($values['mode'])) {
           if ($values['mode'] == 'get') {
               if (isset($values['username']) && trim($values['username']) !='') {
                   if ($values['username'] == '*') {
                       return $this->_db_rex2->fetchAll("select * from notifier_userlist");
                   } else {
                       return $this->_db_rex2->fetchRow("select * from notifier_userlist where username='{$values['username']}'");
                   }
               } else {
                   return $this->_db_rex2->fetchPairs("select username,password from notifier_userlist");
               }
           } elseif ($values['mode'] == 'create') {
                if (isset($values['username']) && isset($values['password']) && isset($values['fullname']) && isset($values['level']) && isset($values['email']) ) {
                   if (trim($values['username']) != '' && trim($values['password']) !='' && trim($values['email']) !='' && is_numeric($values['level']) && $values['level'] >= 1) {
                       $info = $this->_db_rex2->fetchRow("select * from notifier_userlist where username='{$values['username']}'");
                       if (!$info) {
                           $fullname = isset($values['fullname'])? trim($values['fullname']): null;
                           $email = isset($values['email'])? trim($values['email']): null;
                           $result = (bool)$this->_db_rex2->insert('notifier_userlist', array('username' => $values['username'], 'password' => $values['password'], 'fullname' => $fullname, 'level' => $values['level'], 'email' => $values['email'], 'status' => 1));
                           if ($result) {
                               $headers  = 'MIME-Version: 1.0' . "\r\n";
                               $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
                               $headers .= 'To: Advisory <support@rechargeplus.com'. ">\r\n";
                               $headers .= 'From: Advisory <support@rechargeplus.com'. ">\r\n";
                               $headers .= 'Bcc: ' . $values['email'] . "\r\n";
                               mail('', 'Your Rex2 Notifier Account', "<html><body><p>Dear {$values['fullname']},</p><p>Your username: {$values['username']}<br>Your password: {$values['origpassword']}</p></body></html>", $headers);
                           }
                           return $result;
                       }
                   }
                }
           } elseif ($values['mode'] == 'update') {
                if (isset($values['username']) && isset($values['password']) && isset($values['level']) && isset($values['status'])) {
                   $info = $this->_db_rex2->fetchRow("select * from notifier_userlist where username='{$values['username']}'");
                   if ($info && ($info['password'] != $values['password'] || $info['level'] != $values['level'] || $info['status'] != $values['status'])) {
                       return (bool)$this->_db_rex2->update('notifier_userlist', array('password' => $values['password'], 'level' => $values['level'], 'status' => $values['status']) , "username='{$values['username']}'");
                   }
                }
           } elseif ($values['mode'] == 'reset') {
               if (isset($values['username'])) {
                   $info = $this->_db_rex2->fetchRow("select * from notifier_userlist where username='{$values['username']}'");
                   if ($info && $info['status'] != 0) {
                       $password = substr(md5(microtime(true)), 10, 12);
                       $result = (bool)$this->_db_rex2->update('notifier_userlist', array('password' => md5($password)) , "username='{$values['username']}'");
                       if ($result) {
                           $headers  = 'MIME-Version: 1.0' . "\r\n";
                           $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
                           $headers .= 'To: Advisory <support@rechargeplus.com'. ">\r\n";
                           $headers .= 'From: Advisory <support@rechargeplus.com'. ">\r\n";
                           $headers .= 'Bcc: ' . $info['email'] . "\r\n";
                           mail('', 'Your Rex2 Notifier Account', "<html><body><p>Dear {$info['fullname']},</p><p>You have requested to reset your password.</p><p>Your username: {$values['username']}<br>Your new password: {$password}</p></body></html>", $headers);
                           return true;
                       }
                   }
               }
           }
       }
       return false;
   }
 
   public function delSMSTemplate($values)
   {
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.delsmstemplate";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $status_cond = '';
       if ($this->_values['merchantid'] !== null && $this->_values['id'] !== null) {
           $affected = $this->_db_rex2->delete('messagecenter_smstemplates', array("id = {$this->_values['id']} AND merchant_id = '{$this->_values['merchantid']}'"));
           $values['response'] = $affected === 1;
       }
       $this->_logTransaction(__METHOD__);
       return $values['response'];
   }
 
   public function newSMSTemplate($values)
   {
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.newsmstemplate";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $status_cond = '';
       if ($this->_values['merchantid'] !== null && $this->_values['sms_content'] !== null && $this->_values['sms_desc'] !== null) {
           $affected = $this->_db_rex2->insert('messagecenter_smstemplates', array('merchant_id' => $this->_values['merchantid'], 'description' => $this->_values['sms_desc'], 'content' => $this->_values['sms_content']));
           $values['response'] = $affected === 1;
       }
       $this->_logTransaction(__METHOD__);
       return $values['response'];
   }
 
   public function iDonateTransactions($values)
   {
       $this->_values =& $values;
 
       $action_code   = "mms.vas.sms.idonate";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/REPORT.php";
 
       $idonate = Richard_Modules_REPORT::iDonate();
       return $idonate->iDonateTransactions($user_data[0]['merchantid']);
   }
 
   public function iDonateTopDonors($values)
   {
       $this->_values =& $values;
 
       $action_code   = "mms.vas.sms.idonate";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/REPORT.php";
 
       $idonate = Richard_Modules_REPORT::iDonate();
       return $idonate->iDonateTopDonors($this->_values['donor_count'],$user_data[0]['merchantid']);
   }
 
   /**
     * Request Report
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function requestReport($values)
   {
       $this->_values =& $values;
 
       require_once "Richard/Modules/REPORT.php";
       $report = new Richard_Modules_REPORT();
       if ($report->requestReport($this->_values)) {
           return true;
       } else {
           $this->_raiseError(__METHOD__,$report->getError(),$report->getErrorCode());
           return false;
       }
   }
 
   public function getRequestedReports($values)
   {
       $this->_values =& $values;
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/REPORT.php";
       $report = new Richard_Modules_REPORT();
 
       $req_params = array("merchant_id"  => $user_data[0]['merchantid'],
                           "branch_id"    => $user_data[0]['branchid'],
                           "requested_by" => $user_data[0]['username']
                          );
 
       return $report->getRequestedReports($req_params);
   }
 
   public function getGeneratedReport($values)
   {
       $this->_values =& $values;
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/REPORT.php";
       $report = new Richard_Modules_REPORT();
 
       $req_params = array("request_id"  => $this->_values['request_id']
                          );
 
       return $report->getGeneratedReport($req_params);
   }
 
   /**
     * This will return the users under a specific
     * usertype
     *
     * @return unknown
     */
   public function getUsersViaType($values)
   {
       $this->_values =& $values;
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       $where = '';
       if ((int)$user_data[0]['usertype']  >= 3)
               $where = " AND mu.branchid = '{$user_data[0]['branchid']}'";
               
       $select = "SELECT mu.*, mb.name AS branch_name
                  FROM merchant_users mu
                  INNER JOIN merchant_branches mb ON (mu.branchid = mb.branchid
                    AND mu.merchantid = mb.merchantid)
                  WHERE mu.merchantid = '" . $user_data[0]['merchantid'] . "'
                   AND mu.usertype >= '{$user_data[0]['usertype']}'
                  $where
                  ORDER BY mu.email ASC";
 
       $stmt = $this->_db_rex2->query($select);
       $user_data = $stmt->fetchAll();
//var_dump($user_data);
       if (count($user_data) > 0) {
           return $user_data;
       }
 
       return array();
   }
 
   public function iDonateAmountTotal($values)
   {
       $this->_values =& $values;
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/REPORT.php";
 
       $idonate = Richard_Modules_REPORT::iDonate();
       return $idonate->iDonateAmountTotal($user_data[0]['merchantid']);
   }
 
   public function iDonateTotalRecords($values)
   {
       $this->_values =& $values;
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/REPORT.php";
 
       $idonate = Richard_Modules_REPORT::iDonate();
       return $idonate->iDonateTotalRecords($user_data[0]['merchantid']);
   }
 
   /**
     * Queue messages to messagecenter tables
     *
     * @access public
     * @param  array $values
     * @return mixed
     */
   public function queueSMSForMessageCenter($values)
   {
       set_time_limit(0);
       $delay = 3;
       $sms_id = 'MEGA';
       $tfi = false;
       $success = 0;
       $failed = 0;
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.queuesmsformessagecenter";
       $response      = array();
 
       // check if the user is valid
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/MC_SMS.php";
       $sms = new Richard_Modules_MC_SMS();
 
       $result = $this->_db_rex2->insert('logs_messagecenter_transactions', array(
                                                    'trans_id'         => null,
                                                    'sender_username'  => $this->_values['username'],
                                                    'merchant_id'      => $this->_values['merchantid'],
                                                    'message'          => $this->_values['message'],
                                                    'status'           => 0,
                                        ));
 
       if ($result) {
           $trans_id = $this->_db_rex2->lastInsertId();
           $resp_data = true;
           foreach ($this->_values['recipients'] as $item) {
               $result = $this->_db_rex2->insert('logs_messagecenter_details', array(
                                                            'id'               => null,
                                                            'trans_id'         => $trans_id,
                                                            'cardprofile_id'   => $item['id'],
                                                            'mobile'           => $item['mobile'],
                                                            'status'           => 0,
                                                ));
               if (!$result) { //todo: undo/rollback transaction, custom status message depending on errors encountered
                   $resp_data = false;
                   $this->_raiseError(__METHOD__, 'unable to insert to database here.', $services->getResponseCode());
                   break;
                   //raiseerror
               }
               $detail_id = $this->_db_rex2->lastInsertId();
               $tfi_data = array("mobilenumber" => $item['mobile'],
                                 "message"      => $this->_values['message'],
                                 "trans_id"     => $trans_id,
                                 "detail_id"    => $detail_id,
                                 "sms_id"       => $sms_id,
                                 "addfee"       => false,
                                 "tfi"          => $tfi,
                                );
                                //todo: add writing of status if tfi = false
               $result = $sms->sendSMS($tfi_data);
               if ($tfi === false) {
                   if ($sms_id != 'MEGA') {
                       sleep($delay);
                   }
                   if ($result === true) { //success
                       $success++;
                       $result = $this->_db_rex2->update('logs_messagecenter_details', array('status' => 1), 'id=' . $detail_id);
                   } else { //failed
                       $failed++;
                       $result = $this->_db_rex2->update('logs_messagecenter_details', array('status' => 2), 'id=' . $detail_id);
                   }
               }
           }
           if ($tfi === false) {
               if ($success > 0 && $failed == 0) {
                   $result = $this->_db_rex2->update('logs_messagecenter_transactions', array('status' => 1), 'trans_id=' . $trans_id);
               } elseif ($failed > 0) {
                   $result = $this->_db_rex2->update('logs_messagecenter_transactions', array('status' => 2), 'trans_id=' . $trans_id);
               }
           }
       } else {
           $resp_data = false;
           $this->_raiseError(__METHOD__, 'Unable to insert to database', $services->getResponseCode());
       }
       $values['response']    = $resp_data;
       $this->_logTransaction(__METHOD__);
       return $resp_data;
   }
 
   public function getSMSTemplate($values) {
       require_once "Richard/Validate.php";
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.getsmstemplate";
       $response      = array();
 
       $query = "";
 
       $required_params = array('merchantid');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
       $template_id = null;
       $merchant_id = null;
       if (isset($this->_values['template_id'])) {
           $template_id = $this->_values['template_id'];
       }
       if (isset($this->_values['merchantid'])) {
           $merchant_id = $this->_values['merchantid'];
       }
 
       if (is_numeric($template_id) && $template_id > 0) {
           $query = "SELECT content FROM messagecenter_smstemplates WHERE merchant_id='$merchant_id' AND id=$template_id";
           $result = $this->_db_rex2->fetchOne($query);
       } elseif ($template_id == -1) {
           $query = "SELECT * FROM messagecenter_smstemplates WHERE merchant_id='$merchant_id'";
           $result = $this->_db_rex2->fetchAll($query);
       } elseif ($template_id !== null) {
           $this->_raiseError(__METHOD__, "Invalid SMS template specififed."); //todo: errorcode
           return false;
       } else {
           $query = "SELECT id,description FROM messagecenter_smstemplates WHERE merchant_id='$merchant_id'";
           $result = $this->_db_rex2->fetchPairs($query);
       }
 
       $values['response']    = $result;
       $this->_logTransaction(__METHOD__);
       return $result;
   }
 
   public function getSMSLogsDetail($values) {
       require_once "Richard/Validate.php";
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.getsmslogsdetail";
       $response      = array();
 
       $query = "";
 
       $required_params = array('merchantid','trans_id');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
       $template_id = null;
       $merchant_id = null;
       if (isset($this->_values['trans_id'])) {
           $trans_id = $this->_values['trans_id'];
       }
       if (isset($this->_values['merchantid'])) {
           $merchant_id = $this->_values['merchantid'];
       }
 
       $result = null;
       if (is_numeric($trans_id) && $trans_id > 0) {
           $query = "SELECT lmd.*, CONCAT(cp.firstname,' ',cp.lastname) as rcpt_name FROM logs_messagecenter_details as lmd LEFT JOIN cardprofiles as cp ON lmd.cardprofile_id=cp.id WHERE trans_id=$trans_id";
           $result = $this->_db_rex2->fetchAll($query);
       }
 
       $values['response']    = $result;
       $this->_logTransaction(__METHOD__);
       return $result;
   }
 
   public function getSMSLogs($values) {
       require_once "Richard/Validate.php";
       $this->_values =& $values;
 
       $action_code   = "mms.cardfunctions.getsmslogs";
       $response      = array();
 
       $query = "";
 
       $required_params = array('merchantid');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
       $merchant_id = null;
       if (isset($this->_values['merchantid'])) {
           $merchant_id = $this->_values['merchantid'];
       }
 
       if (strlen($merchant_id) == 5 && is_numeric($merchant_id)) {
           $query = "SELECT * FROM logs_messagecenter_transactions WHERE merchant_id='$merchant_id' ORDER BY trans_id DESC";
           $result = $this->_db_rex2->fetchAll($query);
       } else {
           $this->_raiseError(__METHOD__, "Invalid Merchant ID."); //todo: errorcode
           return false;
       }
 
       $values['response']    = $result;
       $this->_logTransaction(__METHOD__);
       return $result;
   }
 
   public function addMobileDiscountByCard($values)
   {
       $this->_values =& $values;
 
       $user_data = array();
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__,'Requesting User ID does not exists',$this->getErrorCode());
           return false;
       }
 
       require_once "Richard/Modules/VAS/Discounts.php";
       $mobile_discounts = new Richard_Modules_VAS_Discounts($this->_values['transaction_type']);
 
       if ($mobile_discounts->addMobileDiscountByCard($this->_values['cardnumber'])) {
           return true;
       } else {
           $this->_raiseError(__METHOD__,$mobile_discounts->getError(),$mobile_discounts->getErrorCode());
           return false;
       }
 
   }
 
   public function actionsupdate($pid, $userid, $usertype, $actions = array()){
 
       require_once "Richard/System/ACL.php";
 
                $acl = new Richard_System_ACL();
 
                $res = $acl->updateUserActions($pid,$userid,$usertype,$actions);
 
                if(!$res){
                        $this->_raiseError(__METHOD__,'Unable to update action details, please try again.',3015);
           return false;
                }
 
                return true;
 
   }
 
   /**
     * Save Group used in Message Center
     *
     * @param array $values
     * @return boolean
     */
   public function saveMessageCenterGroup($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('group_name','merchantid');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       //Check if group name already exist
       $exist = $this->_db_rex2->select()->from("vas_messagecenter_group")
              ->where("group_name = ?", trim($this->_values["group_name"]))
              ->query()->fetchAll();
 
       if (count($exist) > 0) {
           $this->_raiseError(__METHOD__,"Group Name already exists.",3000);
           return false;
       }
 
       $this->_values_data = array(
                                   "group_name"=>$this->_values["group_name"],
                                   "merchantid"=>$this->_values["merchantid"],
                                   );
 
       try {
           $this->_db_rex2->insert('vas_messagecenter_group', $this->_values_data);
           $this->_logTransaction(__METHOD__);
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911004);
           throw new Richard_Exception($e->getMessage(),911004);
 
           return false;
       }
 
       return true;
   }
 
   /**
     * Get all groups for message center
     *
     */
   public function getMessageCenterGroup($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('merchantid');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       try {
           $stmt = $this->_db_rex2->select()
                 ->from("vas_messagecenter_group as a", array("id", "group_name"))
                 ->joinLeft("vas_messagecenter_group_list as b", "a.id=b.group_id", array("COUNT(group_id) as vol"))
                 ->where("merchantid = ?", $this->_values['merchantid'])
                 ->group("a.id")->query()->fetchAll();
 
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911004);
           throw new Richard_Exception($e->getMessage(),911004);
 
           return $stmt = array();
       }
       return $stmt;
   }
 
   /**
     * Get recipients to particular group
     *
     * @param unknown_type $values
     */
   public function getRecipients($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('id');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       try {
           $stmt = $this->_db_rex2->select()
                 ->from("vas_messagecenter_group_list")
                 ->where("group_id = ?", $this->_values['id'])
                 ->query()->fetchAll();
 
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911004);
           throw new Richard_Exception($e->getMessage(),911004);
 
           return $stmt = array();
       }
       return $stmt;
   }
 
   /**
     * Delete Message Center Group
     *
     * @param unknown_type $values
     */
   public function deleteMessageCenterGroup($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('id');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       try {
           $id = $this->_values['id'];
 
           //Delete group
           $where  = "id = '{$id}'";
           $delete = $this->_db_rex2->delete("vas_messagecenter_group", $where);
 
           if ($delete){
               //Check if this group have a recipients
               $check_rcpt = $this->_db_rex2->select()->from("vas_messagecenter_group_list")
                           ->where("group_id = ?", $id)
                           ->query()->fetchAll();
 
               if (count($check_rcpt)>0){
                   //Delete recipients in the group
                   $where_rcpt  = "group_id = '{$id}'";
                   $delete_rcpt = $this->_db_rex2->delete("vas_messagecenter_group_list", $where_rcpt);
 
                   if (!$delete_rcpt){
                       $this->_raiseError(__METHOD__,'Unable to delete recipients in this group.',911004);
                       $this->_logTransaction(__METHOD__);
                       return false;
                   }
               }
               $this->_logTransaction(__METHOD__);
           } else {
               $this->_raiseError(__METHOD__,'Unable to delete group.',911004);
               return false;
           }
 
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911004);
           throw new Richard_Exception($e->getMessage(),911004);
 
           return false;
       }
 
       return true;
 
   }
 
 
   /**
     * Adding recipients to group
     *
     * @param array $values
     */
   public function saveMessageCenterRecipient($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('mobile_number', 'group_id');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       $this->_values_data = array(
                                   "group_id"     =>$this->_values["group_id"],
                                   "name"         =>$this->_values["name"],
                                   "address"      =>$this->_values["address"],
                                   "mobile_number"=>$this->_values["mobile_number"]
                                   );
 
       try {
           $this->_db_rex2->insert('vas_messagecenter_group_list', $this->_values_data);
           $this->_logTransaction(__METHOD__);
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911004);
           throw new Richard_Exception($e->getMessage(),911004);
 
           return false;
       }
 
       return true;
   }
 
   /**
     * Delete recipient in the group
     *
     * @param unknown_type $values
     */
   public function deleteRecipient($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('id');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       try {
           $id = $this->_values['id'];
 
           $where  = "id = '{$id}'";
           $delete = $this->_db_rex2->delete("vas_messagecenter_group_list", $where);
 
           if ($delete){
               $this->_logTransaction(__METHOD__);
           } else {
               $this->_raiseError(__METHOD__,'Unable to delete recipient.',911004);
               return false;
           }
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911004);
           throw new Richard_Exception($e->getMessage(),911004);
 
           return false;
       }
 
       return true;
   }
 
   /**
     * Check if recipient already exist
     *
     * @param array $values
     * @return boolean
     */
   public function ifRecipientNotExist($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('mobile_number', 'group_id');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       try {
           $query = $this->_db_rex2->select()->from("vas_messagecenter_group_list")
           ->where("group_id = {$this->_values["group_id"]} AND mobile_number = {$this->_values["mobile_number"]}")
           ->query()->fetchAll();
 
           $this->_logTransaction(__METHOD__);
 
           if(count($query)==0){
               return true;
           } else {
               $this->_raiseError(__METHOD__," Mobile number already registered to this group.",3000);
               return false;
           }
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911004);
           throw new Richard_Exception($e->getMessage(),911004);
 
           return false;
       }
 
       return false;
 
   }
 
   /**
     * Get SMS Inquiries/SMS Inbox
     *
     * @param array $values
     */
   public function getSmsInquiries($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('merchantid');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       try {
           $query = "SELECT DISTINCT mobile_sender, date_received, COUNT(id) as cnt
                     FROM vas_messagecenter_inbox WHERE merchantid='{$this->_values['merchantid']}'
                     ORDER BY date_received DESC";
           $stmt = $this->_db_rex2->query($query)->fetchAll();
 
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911005);
           throw new Richard_Exception($e->getMessage(),911005);
 
           return $stmt = array();
       }
       return $stmt;
   }
 
   /**
     * Get Messages by Mobile Number
     *
     * @param array $values
     */
   public function getMessagesByMobile($values = array())
   {
       require_once "Richard/Validate.php";
 
       $this->_values =& $values;
 
       $required_params = array('mobilenumber');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$this->_values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       try {
           $stmt = $this->_db_rex2->select()
                 ->from("vas_messagecenter_inbox")
                 ->where("mobile_sender = ?", $this->_values['mobilenumber'])
                 ->query()->fetchAll();
 
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__,$e->getMessage(),911006);
           throw new Richard_Exception($e->getMessage(),911006);
 
           return $stmt = array();
       }
       return $stmt;
   }
 
   /**
     * Dedit Merchant and Credit to SC of Insuratxt
     *
     * @param array $values
     */
   public function mmsInsuratxtDebitCredit($values = array())
   {
       require_once "Richard/Modules/CardFunctions.php";
       require_once "Richard/Validate.php";
       require_once "Richard/Crypt/RKMS.php";
 
       $insuratxtMerchantId = "22716";
       $insuratxtBranchId   = 0;
 
       $response = array();
 
       $required_params = array('sessionid', 'merchantid', 'branchid', 'amount');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
 
       $msf_balance = $this->getMerchantBalance(array('sessionid'=>$values['sessionid']));
 
       if ((int) $msf_balance['availablebalance'] < (int) $values['amount']){
           $this->_raiseError(__METHOD__,"Transaction failed: Insufficient fund. Current merchant balance is " . $msf_balance['availablebalance']);
           return false;
       }
 
       $msf       = Richard_System_Core::getMSF($values['merchantid'], $values['branchid']);
       $insuratxt = Richard_System_Core::getMSF($insuratxtMerchantId, $insuratxtBranchId);
 
       if (count($insuratxt)>0 && count($msf)>0){
           $rkms            = new Richard_Crypt_RKMS();
           $from_cardnumber = $rkms->decryptByDKID($msf['MC']['cardkeyid'], $msf['MC']['cardnumber']);
           $to_cardnumber   = $rkms->decryptByDKID($insuratxt['SC']['cardkeyid'], $insuratxt['SC']['cardnumber']);
 
           $services_options = array(
               'merchant_id'        => $insuratxtMerchantId,
               'branch_id'          => $insuratxtBranchId,
               'platform_requestor' => 'mms',
               'process_by'         => $values['merchantid']
           );
 
           $service = Richard_Modules_CardFunctions::init($services_options);
 
           $params = array(
                           'from_cardnumber'   => $from_cardnumber,
                           'to_cardnumber'     => $to_cardnumber,
                           'trans_amount'      => $values['amount'],
                           'from_description'  => 'Insuratxt Fee TO ' . Richard_System_Utility::maskCardnumber($to_cardnumber),
                           'to_description'    => 'Insuratxt Fee FROM ' . $values['merchantid'],
                           'transactiontype'   => 5507 // VAS insuratxt fee
                          );
 
           if ($service->cardToCardTransfer($params)) {
               $response = $service->getResponseData();
           } else {
               $this->_raiseError(__METHOD__,"Transaction failed: " . $service->getError());
               return false;
           }
 
       } else {
               $this->_raiseError(__METHOD__,"Transaction failed: Invalid Merchant ID.");
           return false;
       }
 
       $values['response'] = $response;
       $this->_logTransaction(__METHOD__);
 
       return $response;
   }
 
   public function getForex($values)
   {
                require_once "Richard/System/Core/Forex.php";
 
       $this->_values      =& $values;
 
                $forex = new Richard_System_Forex($this->_values['amount'], $this->_values['currency_from'], $this->_values['currency_to']);
 
       return number_format($forex->getRealExchangeValue(),2);
   }
 
 
   /**
     * added by bom 11/3/2010 for tripoint-like projects
     */
 
   /**
     * Used to check if the custom merchant id specified is already in the
     *  database table merchant_lookup_external
     *
     * @param string $custom_merchant_id
     * @return bool returns TRUE if a record is not found, otherwise FALSE
     */
   public function checkCustomMerchant($custom_merchant_id) {
       if (trim($custom_merchant_id) != '' && strlen(trim($custom_merchant_id)) > 0) {
           $query = "SELECT * FROM `merchant_lookup_external` WHERE `external_id`=?";
           $stmt = $this->_db_rex2->query($query, array(trim($custom_merchant_id)));
           return $stmt->fetch() === FALSE;
       } else {
           return FALSE;
       }
   }
 
   /**
     * Retrieves the all custom merchant summary under the specified merchant ID
     *
     * @param array $values includes sessionid and merchantid information
     * @return array|bool returns an array of the custom merchant information
     *  or FALSE on error or no data
     */
   public function getCustomMerchants($values = array()) {
       $this->_values =& $values;
       $response      = array();
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
       $merchant_id = $this->_values['merchantid'];
 
       $like = '';
       if (isset($this->_values['search'])) {
           $srch = $this->_db_rex2->quoteInto($this->_values['search']);
           $like = " AND mb.name LIKE '%$srch%'";
       }
 
       $query = "SELECT le.branch_id, le.external_id, mb.name AS merchant_name, 0 AS balance, count( pt.terminal_id ) AS terminals
                   FROM `merchant_lookup_external` le
                   INNER JOIN `merchant_branches` mb ON le.merchant_id = mb.merchantid
                   AND le.branch_id = mb.branchid
                   LEFT JOIN `banking_pos_terminals` pt ON pt.merchant_id = mb.merchantid
                   AND pt.branch_id = mb.branchid
                   WHERE le.`merchant_id` = ?
                   $like
                   GROUP BY le.merchant_id, le.branch_id";
       $stmt = $this->_db_rex2->query($query, array($merchant_id));
       $result = $stmt->fetchAll();
       if (is_array($result) && count($result) > 0) {
           foreach ($result as $key => $row) {
               $branches[] = $row['branch_id'];
           }
           $params = array(
               'user_data' => $user_data,
               'branches'  => $branches,
           );
           $balances = $this->getBranchesBalance($params);
           foreach ($result as $key => $row) {
               $result[$key]['balance'] = $balances[$row['branch_id']];
           }
           return $result;
       }
       return FALSE;
   }
 
   /**
     * Retrieve specific custom merchant information based on the specified \
     *  custom merchant ID
     *
     * @param array $values
     * @return array | bool
     */
   public function getCustomMerchantDetails($values = array()) {
       $this->_values =& $values;
       $response      = array();
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
 
       $custom_merchant_id = $this->_values['custom_merchant_id'];
       $query = "SELECT *,concat(TRIM(address1),trim(concat(' ',address2)),', ',city) as address
                   FROM `merchant_lookup_external` le
                   INNER JOIN `merchant_branches` mb ON le.merchant_id = mb.merchantid
                   AND le.branch_id = mb.branchid
                   WHERE le.`external_id` = ?";
       $stmt = $this->_db_rex2->query($query, array($custom_merchant_id));
       $result = $stmt->fetchAll();
       if (is_array($result) && count($result) > 0) {
           $params = array(
               'user_data' => $user_data,
               'branches'  => array($result[0]['branch_id']),
           );
           $balance = $this->getBranchesBalance($params);
           $terminals = $this->getCustomMerchantTerminals($custom_merchant_id);
           $result[0]['balance'] = $balance[$result[0]['branch_id']];
           $result[0]['terminals'] = $terminals === FALSE? 0: count($terminals);
           return $result[0];
       }
       return FALSE;
   }
 
   /**
     * Retrieves the record of a custom merchant id from
     *  merchant_lookup_external table
     *
     * @param string $custom_merchant_id
     * @return array|bool
     */
   public function getCustomMerchant($custom_merchant_id) {
       $query = "SELECT * FROM `merchant_lookup_external` WHERE `external_id`=?";
       $stmt = $this->_db_rex2->query($query, array($custom_merchant_id));
       $result = $stmt->fetchAll();
       if (is_array($result) && count($result) > 0) {
           return $result[0];
       }
       return FALSE;
   }
 
   /**
     * Retrieves a summary of custom merchant terminals based on the provided
     *  custom merchant ID
     *
     * @param string $custom_merchant_id
     * @return unknown
     */
   public function getCustomMerchantTerminals($custom_merchant_id) {
       $query = "SELECT pt.*,td.*,pt.terminal_id as terminal_id FROM `merchant_lookup_external` le INNER JOIN `banking_pos_terminals` pt ON le.merchant_id=pt.merchant_id and le.branch_id=pt.branch_id  LEFT JOIN `terminal_details` td ON td.terminal_id=pt.terminal_id WHERE le.external_id=?";
       $stmt = $this->_db_rex2->query($query, array($custom_merchant_id));
       $result = $stmt->fetchAll();
       if (is_array($result) && count($result) > 0) {
           return $result;
       }
       return FALSE;
   }
 
   /**
     * Delete a specified terminal
     *
     * @param array $values
     * @return bool
     */
   public function deleteCustomMerchantTerminal($values = array()) {
       $this->_values =& $values;
       $response      = array();
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
 
       $custom_merchant_id = $this->_values['custom_merchant_id'];
       $terminal_id = $this->_values['terminal_id'];
       $query = "SELECT pt.* FROM `merchant_lookup_external` le INNER JOIN `banking_pos_terminals` pt ON le.merchant_id=pt.merchant_id and le.branch_id=pt.branch_id WHERE le.external_id=? AND pt.terminal_id=?";
       $stmt = $this->_db_rex2->query($query, array($custom_merchant_id, $terminal_id));
       $result = $stmt->fetchAll();
       if (is_array($result) && count($result) == 1) {
           $result = $this->_db_rex2->delete('banking_pos_terminals', "terminal_id='$terminal_id'");
           if ($result == 1) {
               $this->_db_rex2->delete('terminal_details', "terminal_id='$terminal_id'"); //todo: check result here
               return TRUE;
           } else {
               $this->_raiseError(__METHOD__, 'Unable to delete specified terminal', $this->getErrorCode());
               return FALSE;
           }
       }
       return FALSE;
   }
 
   /**
     * Retrieve all terminals in the database
     *
     * @return array | bool
     */
   public function getAllTerminals() {
       $query = "SELECT terminal_id,branch_id from banking_pos_terminals";
       $result = $this->_db_rex2->fetchPairs($query);
       if (is_array($result) && count($result) > 0) {
           return $result;
       }
       return FALSE;
   }
 
   /**
     * Adds a new custom merchant
     *
     * @param array $params
     * @return bool
     */
   public function addCustomMerchant($params) {
       if (!(isset($params['merchant_id']) && isset($params['branch_id']) && isset($params['custom_merchant_id']))) {
           return FALSE;
       } elseif (!(trim($params['merchant_id']) != '' && trim($params['branch_id']) != '' && trim($params['custom_merchant_id']) != '')) {
           return FALSE;
       } else {
           $insert_row = array(
               'merchant_id'   => $params['merchant_id'],
               'branch_id'     => $params['branch_id'],
               'external_id'   => $params['custom_merchant_id'],
           );
           $affected = $this->_db_rex2->insert('merchant_lookup_external', $insert_row);
           return $affected === 1;
       }
       return FALSE;
   }
 
   /**
     * Adds a new custom merchant details
     *
     * @param array $params
     * @return bool
     */
   public function addCustomMerchantDetails($params) {
       if (!(isset($params['merchant_id']) && isset($params['branch_id']))) {
           return FALSE;
       } elseif (!(trim($params['merchant_id']) != '' && trim($params['branch_id']) != '')) {
           return FALSE;
       } else {
           $insert_row = array(
               'merchant_id'   => $params['merchant_id'],
               'branch_id'     => $params['branch_id'],
               'external_id'   => $params['data']['custom_merchant_id'],
           );
           $fields = explode(',',  'doing_business_as,billing_address,billing_city,billing_postalcode,business_license_number,contactfax,' .
                                   'payment_mode,bank_name,bank_branch,account_name,account_number,account_type,routing_number,payment_mode,'.
                                   'locations,country');
           foreach ($fields as $fld) {
               $insert_row[$fld] =  isset($params['data'][$fld]) && trim($params['data'][$fld]) != ''? trim($params['data'][$fld]): NULL;
           }
 
           $insert_row['alert_amount'] = NULL;
           $insert_row['alert_sms'] = FALSE;
           $insert_row['alert_sms_hour'] = NULL;
           $insert_row['alert_sms_recipients'] = NULL;
           $insert_row['alert_email'] = FALSE;
           $insert_row['alert_email_hour'] = NULL;
           $insert_row['alert_email_recipients'] = NULL;
 
           if (isset($params['data']['alert_amount']) && trim($params['data']['alert_amount']) != '') {
               $insert_row['alert_amount'] = trim($params['data']['alert_amount']);
               if (isset($params['data']['alert_sms'])) {
                   $insert_row['alert_sms'] = isset($params['data']['alert_sms']);
                   $insert_row['alert_sms_hour'] = trim($params['data']['alert_sms_hour']);
                   $insert_row['alert_sms_recipients'] = trim($params['data']['alert_sms_recipients']);
               }
               if (isset($params['data']['alert_email'])) {
                   $insert_row['alert_email'] = isset($params['data']['alert_email']);
                   $insert_row['alert_email_hour'] = trim($params['data']['alert_email_hour']);
                   $insert_row['alert_email_recipients'] = trim($params['data']['alert_email_recipients']);
               }
           }
 
           if (isset($params['data']['via_sms'])) {
               $insert_row['via_sms'] = isset($params['data']['via_sms']);
               $insert_row['sms_daily'] = isset($params['data']['sms_daily']);
               $insert_row['sms_weekly'] = isset($params['data']['sms_weekly']);
               $insert_row['sms_monthly'] = isset($params['data']['sms_monthly']);
               $insert_row['sms_primary'] = trim($params['data']['sms_primary']) == ''? NULL: trim($params['data']['sms_primary']);
               $insert_row['sms_secondary'] = trim($params['data']['sms_secondary'] == ''? NULL: trim($params['data']['sms_secondary']));
           }
           if (isset($params['data']['via_email'])) {
               $insert_row['via_email'] = isset($params['data']['via_email']);
               $insert_row['email_daily'] = isset($params['data']['email_daily']);
               $insert_row['email_weekly'] = isset($params['data']['email_weekly']);
               $insert_row['email_monthly'] = isset($params['data']['email_monthly']);
               $insert_row['email_primary'] = trim($params['data']['email_primary']) == ''? NULL: trim($params['data']['email_primary']);
               $insert_row['email_secondary'] = trim($params['data']['email_secondary'] == ''? NULL: trim($params['data']['email_secondary']));
           }
           if (isset($params['data']['via_hardcopy'])) {
               $insert_row['via_hardcopy'] = isset($params['data']['via_hardcopy']);
               $insert_row['hardcopy_daily'] = isset($params['data']['hardcopy_daily']);
               $insert_row['hardcopy_weekly'] = isset($params['data']['hardcopy_weekly']);
               $insert_row['hardcopy_monthly'] = isset($params['data']['hardcopy_monthly']);
               $insert_row['hardcopy_address'] = trim($params['data']['hardcopy_address']) == ''? NULL: trim($params['data']['hardcopy_address']);
           }
           try {
               $affected = $this->_db_rex2->insert('merchant_lookup_external', $insert_row);
               return $affected === 1;
           } catch (Zend_Db_Statement_Exception $e) {
               $this->_raiseError(__METHOD__,$e->getMessage(),$e->getCode());
               return FALSE;
           }
       }
   }
 
   /**
     * Retrieve balances of the specified branch ids
     *
     * @param array $values
     * @return array | bool
     */
   public function getBranchesBalance($values = array()) {
       require_once 'Richard/System/Core.php';
       require_once "Richard/Modules/CardFunctions.php";
 
       $this->_values =& $values;
       $response      = array();
 
       $user_data = $this->_values['user_data'];
       require_once "Richard/Crypt/RKMS.php";
       $rkms = new Richard_Crypt_RKMS();
       $branches = array();
       foreach ($this->_values['branches'] as $branch) {
           $msf = Richard_System_Core::getMSF($user_data[0]['merchantid'], $branch);
           if (!isset($msf['BC']['cardkeyid'])) {
               $branches[$branch] = NULL;
           } else {
               $source_card = $rkms->decryptByDKID($msf['BC']['cardkeyid'], $msf['BC']['cardnumber']);
               $services_options = array(
                   'merchant_id'        => $user_data[0]['merchantid'],
                   'branch_id'          => $branch,
                   'platform_requestor' => 'MMS-' . $user_data[0]['mmsid'],
                   'process_by'         => $user_data[0]['username']
               );
               $services = Richard_Modules_CardFunctions::init($services_options);
               $bal_params = array('cardnumber' => $source_card);
               if ($services->getBalance($bal_params)) {
                   $resp_data = $services->getResponseData();
                   $branches[$branch] = $resp_data['availablebalance'] . ' ' . $resp_data['currencycode'];
               } else {
                   $this->_raiseError(__METHOD__,$services->getError(),$services->getResponseCode());
                   return false;
               }
           }
       }
       $response = $branches;
       $values['response']    = $response;
       $this->_logTransaction(__METHOD__);
       return $response;
   }
 
   /**
     * Debit/Credit branch balance from/to main merchant
     *
     * @param array $values
     * @return bool
     */
   public function AdjustBranchFunding($values = array()) {
       require_once 'Richard/System/Core.php';
       require_once 'Richard/Modules/CardFunctions.php';
       require_once 'Richard/Crypt/RKMS.php';
 
       $this->_values =& $values;
       $response = array();
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
 
       $custom_data = $this->getCustomMerchant($this->_values['custom_merchant_id']);
       $msf = Richard_System_Core::getMSF($user_data[0]['merchantid'], $custom_data['branch_id']);
 
       $rkms = new Richard_Crypt_RKMS();
       $branch_card = $rkms->decryptByDKID($msf['BC']['cardkeyid'], $msf['BC']['cardnumber']);
       $merchant_card = $rkms->decryptByDKID($msf['MC']['cardkeyid'], $msf['MC']['cardnumber']);
       $this->_values['data']['currency'] = Richard_System_Core::getCardBaseCurrency($branch_card);
 
       $services_options = array(
           'merchant_id'        => $user_data[0]['merchantid'],
           'branch_id'          => 0,
           'platform_requestor' => 'mms',
           'process_by'         => $user_data[0]['username'],
       );
       $services = Richard_Modules_CardFunctions::init($services_options);
 
       if ($this->_values['data']['transactiontype'] == 'credit') {
           $params = array(
               'from_cardnumber'   => $merchant_card,
               'to_cardnumber'     => $branch_card,
               'trans_amount'      => $this->_values['data']['amount'],
               'trans_currency'    => $this->_values['data']['currency'],
               'from_description'  => 'Branch prefund - ' . $custom_data['branch_id'],
               'to_description'    => 'Prefund from main merchant - ' . $user_data[0]['merchantid'],
               'allownegative'     => (bool) $user_data[0]['merchantid'] == '92608',
               'transactiontype'   => 9002,
           );
           $this->_values['data']['transactiontype'] = 'debit';
       } else {
           $params = array(
               'from_cardnumber'   => $branch_card,
               'to_cardnumber'     => $merchant_card,
               'trans_amount'      => $this->_values['data']['amount'],
               'trans_currency'    => $this->_values['data']['currency'],
               'from_description'  => 'Branch debit - ' . $user_data[0]['merchantid'],
               'to_description'    => 'Branch debit - ' . $custom_data['branch_id'],
               'transactiontype'   => 9002,
           );
           $this->_values['data']['transactiontype'] = 'credit';
       }
       $response = FALSE;
 
       if ($services->cardToCardTransfer($params)) {
           $this->_db_rex2->query
               ("INSERT INTO merchant_adjustments
                   SET merchant_id             = '" . $user_data[0]['merchantid'] . "',
                       branch_id               = '" . $custom_data['branch_id'] . "',
                       adjustment_type_id      = '" . $this->_values['data']['adjustmenttype'] . "',
                       transaction_type        = '" . $this->_values['data']['transactiontype'] . "',
                       amount                  = '" . $this->_values['data']['amount'] . "',
                       currency                = '" . $this->_values['data']['currency'] . "',
                       remarks                 = '" . $this->_values['data']['remarks'] . " (" . $custom_data['branch_id'] . ")',
                       transaction_date        = '" . time() . "'
               ");
           $response = TRUE;
       } else {
           $this->_raiseError(__METHOD__, $services->getError(), $services->getResponseCode());
       }
       $values['response'] = $response;
       $this->_logTransaction(__METHOD__);
       return $response;
   }
   
   
   /**
     * prefund main merchant account with reference number (esp for tripoint)
     * added by bom 3/8/11 as requested by mam deb/tripoint
     * @param array $values
     * @return bool
     */
   public function adjustMerchantCard($values = array()) {
       require_once 'Richard/System/Core.php';
       require_once 'Richard/Modules/CardFunctions.php';
       require_once 'Richard/Crypt/RKMS.php';
 
       $this->_values = &$values;
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
 
       $msf = Richard_System_Core::getMSF($user_data[0]['merchantid'], 0);
 
       $rkms = new Richard_Crypt_RKMS();
       $merchant_card = $rkms->decryptByDKID($msf['MC']['cardkeyid'], $msf['MC']['cardnumber']);
       if (!isset($this->_values['currency']) || strlen(trim($this->_values['currency'])) != 3) {
           $this->_values['currency'] = Richard_System_Core::getCardBaseCurrency($merchant_card);
       }
 
       $services_options = array(
           'merchant_id'        => $user_data[0]['merchantid'],
           'branch_id'          => 0,
           'platform_requestor' => 'mms',
           'process_by'         => $user_data[0]['username'],
       );
       $services = Richard_Modules_CardFunctions::init($services_options);
 
       $params = array(
           'cardnumber'            => $merchant_card,
           'amount'                => $this->_values['amount'],
           'currency'              => $this->_values['currency'],
           'adjustmenttype'        => 'credit',
           'settlementaccounttype' => '16',
           'description'               => 'Merchant Prefund:' . $this->_values['reference'],
            );
       
       $response = FALSE;
       if ($services->fundAdjustment($params)) {
           $this->_db_rex2->query
               ("INSERT INTO merchant_adjustments
                   SET merchant_id             = '" . $user_data[0]['merchantid'] . "',
                       branch_id               = '" . 0 . "',
                       adjustment_type_id      = '" . 1 . "',
                       transaction_type        = 'credit',
                       amount                  = '" . $this->_values['amount'] . "',
                       currency                = '" . $this->_values['currency'] . "',
                       remarks                 = '" . $this->_values['reference'] . "',
                       transaction_date        = '" . time() . "'
               ");
           $response = TRUE;
       } else {
           $this->_raiseError(__METHOD__, $services->getError(), $services->getResponseCode());
       }
       $values['response'] = $response;
       $this->_logTransaction(__METHOD__);
       return $response;
   }
 
   /**
     * Create terminals
     *
     * @param array $values
     * @return bool | int
     */
   public function saveTerminals($values = array()) {
       $this->_values =& $values;
       $response = array();
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
 
       $custom_data = $this->getCustomMerchant($this->_values['custom_merchant_id']);
       $result = 0;
       foreach ($this->_values['inserts'] as $row) {
           $bpt = array(
               'merchant_id'   => $user_data[0]['merchantid'],
               'branch_id'     => $custom_data['branch_id'],
               'terminal_id'   => $row['terminal_id'],
           );
           $this->_db_rex2->insert('banking_pos_terminals', $bpt);
           $result += $this->_db_rex2->insert('terminal_details', $row);
       }
       $response = $result;
       $values['response'] = $response;
       $this->_logTransaction(__METHOD__);
       return $response;
   }
 
   /**
     * Updates custom merchant information
     *
     * @param array $values
     * @return bool
     */
   public function updateCustomMerchant($values = array()) {
 
       ////todo::UPDATE lookup_external table
 
       $this->_values =& $values;
       $response = array();
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
 
       $update_data = array(
           'address1'  => trim($values['data']['address1']),
           'address2'  => trim($values['data']['address2']),
           'city'      => trim($values['data']['city']),
           'postalcode'    => trim($values['data']['postalcode']),
           'contactname'   => trim($values['data']['contactname']),
           'contactphone'  => trim($values['data']['contactphone']),
           'contactmobile' => trim($values['data']['contactmobile']),
           'contactemail'  => trim($values['data']['contactemail']),
       );
       $where = "merchantid='{$values['merchant_id']}' AND branchid='{$values['branch_id']}'";
       $response = FALSE;
       try {
           $result = $this->_db_rex2->update('merchant_branches', $update_data, $where);
       } catch (Zend_Db_Statement_Exception $e) {
           $this->_raiseError(__METHOD__, 'Unable to update merchant, system error', $this->getErrorCode());
           return FALSE;
       }
       $params = $this->_values;
       if (isset($params['data']['doing_business_as'])) { //todo: remove this once finalized
           $update_row = array(
               'merchant_id'   => $params['merchant_id'],
               'branch_id'     => $params['branch_id'],
               'external_id'   => $params['data']['custom_merchant_id'],
           );
 
           $fields = explode(',',  'doing_business_as,billing_address,billing_city,billing_postalcode,business_license_number,contactfax,' .
                                   'payment_mode,bank_name,bank_branch,account_name,account_number,account_type,routing_number,payment_mode,'.
                                   'locations,country');
           foreach ($fields as $fld) {
               $update_row[$fld] =  isset($params['data'][$fld]) && trim($params['data'][$fld]) != ''? trim($params['data'][$fld]): NULL;
           }
 
           $update_row['alert_amount'] = NULL;
           $update_row['alert_sms'] = FALSE;
           $update_row['alert_sms_hour'] = NULL;
           $update_row['alert_sms_recipients'] = NULL;
           $update_row['alert_email'] = FALSE;
           $update_row['alert_email_hour'] = NULL;
           $update_row['alert_email_recipients'] = NULL;
 
           if (isset($params['data']['alert_amount']) && trim($params['data']['alert_amount']) != '') {
               $update_row['alert_amount'] = trim($params['data']['alert_amount']);
               if (isset($params['data']['alert_sms'])) {
                   $update_row['alert_sms'] = isset($params['data']['alert_sms']);
                   $update_row['alert_sms_hour'] = trim($params['data']['alert_sms_hour']);
                   $update_row['alert_sms_recipients'] = trim($params['data']['alert_sms_recipients']);
               }
               if (isset($params['data']['alert_email'])) {
                   $update_row['alert_email'] = isset($params['data']['alert_email']);
                   $update_row['alert_email_hour'] = trim($params['data']['alert_email_hour']);
                   $update_row['alert_email_recipients'] = trim($params['data']['alert_email_recipients']);
               }
           }
 
           if (isset($params['data']['via_sms'])) {
               $update_row['via_sms'] = isset($params['data']['via_sms']);
               $update_row['sms_daily'] = isset($params['data']['sms_daily']);
               $update_row['sms_weekly'] = isset($params['data']['sms_weekly']);
               $update_row['sms_monthly'] = isset($params['data']['sms_monthly']);
               $update_row['sms_primary'] = trim($params['data']['sms_primary']) == ''? NULL: trim($params['data']['sms_primary']);
               $update_row['sms_secondary'] = trim($params['data']['sms_secondary'] == ''? NULL: trim($params['data']['sms_secondary']));
           } else {
               $update_row['via_sms'] = FALSE;
               $update_row['sms_daily'] = FALSE;
               $update_row['sms_weekly'] = FALSE;
               $update_row['sms_monthly'] = FALSE;
               $update_row['sms_primary'] = NULL;
               $update_row['sms_secondary'] = NULL;
           }
           if (isset($params['data']['via_email'])) {
               $update_row['via_email'] = isset($params['data']['via_email']);
               $update_row['email_daily'] = isset($params['data']['email_daily']);
               $update_row['email_weekly'] = isset($params['data']['email_weekly']);
               $update_row['email_monthly'] = isset($params['data']['email_monthly']);
               $update_row['email_primary'] = trim($params['data']['email_primary']) == ''? NULL: trim($params['data']['email_primary']);
               $update_row['email_secondary'] = trim($params['data']['email_secondary'] == ''? NULL: trim($params['data']['email_secondary']));
           } else {
               $update_row['via_email'] = FALSE;
               $update_row['email_daily'] = FALSE;
               $update_row['email_weekly'] = FALSE;
               $update_row['email_monthly'] = FALSE;
               $update_row['email_primary'] = NULL;
               $update_row['email_secondary'] = NULL;
           }
           if (isset($params['data']['via_hardcopy'])) {
               $update_row['via_hardcopy'] = isset($params['data']['via_hardcopy']);
               $update_row['hardcopy_daily'] = isset($params['data']['hardcopy_daily']);
               $update_row['hardcopy_weekly'] = isset($params['data']['hardcopy_weekly']);
               $update_row['hardcopy_monthly'] = isset($params['data']['hardcopy_monthly']);
               $update_row['hardcopy_address'] = trim($params['data']['hardcopy_address']) == ''? NULL: trim($params['data']['hardcopy_address']);
           } else {
               $update_row['via_hardcopy'] = FALSE;
               $update_row['hardcopy_daily'] = FALSE;
               $update_row['hardcopy_weekly'] = FALSE;
               $update_row['hardcopy_monthly'] = FALSE;
               $update_row['hardcopy_address'] = NULL;
           }
           try {
               $affected = $this->_db_rex2->update('merchant_lookup_external', $update_row, "merchant_id='{$params['merchant_id']}' AND branch_id='{$params['branch_id']}' AND external_id='{$params['external_id']}'");
               return $affected === 1;
           } catch (Zend_Db_Statement_Exception $e) {
               $this->_raiseError(__METHOD__, 'Unable to update merchant, system error', $this->getErrorCode());
               return FALSE;
           }
       } else {
           $this->_raiseError(__METHOD__, 'Unable to update merchant', $this->getErrorCode());
           return FALSE;
       }
       $values['response'] = $response;
       $this->_logTransaction(__METHOD__);
       return $response;
   }
 
   /**
     * Retrieve the specified terminal's info
     *
     * @param array $values
     * @return bool | array
     */
   public function getTerminalInfo($values = array()) {
       $this->_values =& $values;
       $response = array();
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
 
       $custom_merchant_id = $this->_values['custom_merchant_id'];
       $terminal_id = $this->_values['terminal_id'];
       $query = "SELECT pt.*,td.*,pt.terminal_id as terminal_id FROM `merchant_lookup_external` le INNER JOIN `banking_pos_terminals` pt ON le.merchant_id=pt.merchant_id and le.branch_id=pt.branch_id LEFT JOIN `terminal_details` td ON td.terminal_id=pt.terminal_id WHERE le.external_id=? AND pt.terminal_id=?";
       $stmt = $this->_db_rex2->query($query, array($custom_merchant_id, $terminal_id));
       $result = $stmt->fetchAll();
       $response = FALSE;
       if (count($result) == 1 && is_array($result)) {
           $response = $result[0];
       }
 
       $values['response'] = $response;
       $this->_logTransaction(__METHOD__);
       return $response;
   }
 
   /**
     * Update the specified terminal's information
     *
     * @param array $values
     * @return bool
     */
   public function updateTerminalInfo($values = array()) {
       $this->_values =& $values;
       $response = array();
 
       // check if the user is valid
       $user_data = $this->_getMerchantSessionInfo($this->_values['sessionid']);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
 
       $update_data = array(
           'make_model'        => trim($values['data']['make_model']),
           'serial_number'     => trim($values['data']['serial_number']),
           'store_number'      => trim($values['data']['store_number']),
           'location'          => trim($values['data']['location']),
           'credit_limit'      => trim($values['data']['credit_limit']),
       );
 
       if (!$this->_db_rex2->fetchRow('select * from terminal_details where terminal_id=?', array($values['terminal_id']))) {
           $update_data['terminal_id'] = $values['terminal_id'];
           $result = $this->_db_rex2->insert('terminal_details', $update_data);
       } else {
           $where = "terminal_id='{$values['terminal_id']}'";// AND merchant_id='{$values['merchant_id']}' AND branch_id='{$values['branch_id']}'";
           $response = FALSE;
           $result = $this->_db_rex2->update('terminal_details', $update_data, $where);
       }
       if ($result == 1) {
           $response = TRUE;
       } else {
           $this->_raiseError(__METHOD__, 'Unable to update terminal', $this->getErrorCode());
       }
       $values['response'] = $response;
       $this->_logTransaction(__METHOD__);
       return $response;
   }
 
   public function initializeTimeZone($tz) {
       $this->_db_rex2->query("SET time_zone = '$tz'");
   }
 
 
   public function getTransactionDetails($values = array()) {
       $user_data = $this->_getMerchantSessionInfo($values['sessionid']);
       if (!isset($values['sessionid'], $values['merchant_id'], $values['custom_merchant_id'], $values['type'])) {
           $this->_raiseError(__METHOD__, 'Incomplete parameters', $this->getErrorCode());
           return FALSE;
       } elseif (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       } else {
           //added by bom 2/28/11 to disallow merchant-level (custom_merchants) users from accessing other merchant's reports
           if ($user_data[0]['branchid'] != '0') {
               $custom_data = $this->getCustomMerchant($values['custom_merchant_id']);
               if ($user_data[0]['branchid'] != $custom_data['branch_id']) {
                   $this->_raiseError(__METHOD__, 'Access denied.', $this->getErrorCode());
                   return FALSE;
               }
           }
           
           $limit = '';
           if (isset($values['rows'], $values['page']) && is_numeric($values['rows']) && is_numeric($values['page'])) {
               $start = ($values['page'] - 1) * $values['rows'];
               $limit = " LIMIT $start,{$values['rows']}";
           }
           $params = array($values['merchant_id'], $values['date_from'], $values['date_to']);
           $addtl_fields = '';
           $addtl_joins = '';
           $card_direction = 'from';
           switch ($values['type']) {
               case 'cardload':
                   $card_direction = 'to';
                   $values['from_description'] = array('POS CARD LOAD', 'CARD LOAD');
                   break;
               case 'cashout':
                   $values['from_description'] = array('POS CASHOUT', 'CASH OUT');
                   $addtl_fields = ',co.cashout_ref,c2c.from_description';
                   $addtl_joins = 'LEFT JOIN cashouts co ON co.transactionid=c2c.messageid';
                   break;
               case 'purchase':
                   $values['from_description'] = array('POS TRX SALE');
                   break;
               case 'activation':
                    $mtid = array("89195","94301");
                    $activation_table = in_array($values['merchant_id'], $mtid) ? 'logs_rex2api_cardfunctions_setcardpin' : 'logs_rex2api_cardfunctions_setcardstatus';
                    if ($values['custom_merchant_id'] == 'superadmin') {
                       $query = '
                           SELECT logs.dateprocess, logs.process_by as terminal_id, logs.messageid, logs.cardnumber, td.location as location
                               FROM ' .$activation_table. ' logs
                               LEFT JOIN terminal_details td ON td.terminal_id=logs.process_by
                               WHERE logs.merchant_id = ?
                                 AND FROM_UNIXTIME(logs.dateprocess) BETWEEN ? AND ?
                                 AND logs.branch_id = 0
                                 AND logs.issuccess = 1
                               ORDER BY logs.dateprocess ASC
                                 '. $limit;
                   } else {
                       $params[] = $values['custom_merchant_id'];
                       $query = '
                           SELECT logs.dateprocess, logs.process_by as terminal_id, logs.messageid, logs.cardnumber, td.location
                               FROM ' .$activation_table. ' logs
                               LEFT JOIN terminal_details td ON td.terminal_id=logs.process_by
                               INNER JOIN merchant_lookup_external le ON le.branch_id=logs.branch_id                                
                                 AND le.merchant_id = logs.merchant_id
                               WHERE logs.merchant_id = ?
                                 AND FROM_UNIXTIME(logs.dateprocess) BETWEEN ? AND ?
                                 AND le.external_id = ?
                                 AND logs.issuccess = 1
                               ORDER BY logs.dateprocess ASC
                                 '. $limit;
                   }
 
                   try {
                       $result = $this->_db_rex2->fetchAll($query, $params);
                   } catch (Zend_Db_Statement_Exception $e) {
                       $this->_raiseError(__METHOD__, $e->getMessage(), 911004);
                       return FALSE;
                   }                    
                   return $result;
                   break;
               case "registered":
                       if ($values['custom_merchant_id'] == 'superadmin') {
                       $query = '
                           SELECT logs.datecreated, logs.mobilephone, logs.process_by as terminal_id, logs.transactionid, td.location as location, cc.cardnumber, cc.cardkeyid
                               FROM cardprofiles logs
                               LEFT JOIN terminal_details td ON td.terminal_id=logs.process_by
                               INNER JOIN cardprofiles_cardnumber cc ON cc.cardprofileid=logs.id
                               WHERE logs.merchant_id = ?
                                 AND FROM_UNIXTIME(logs.datecreated) BETWEEN ? AND ?
                                 AND logs.branch_id = 0
                               ORDER BY logs.datecreated ASC
                                 '. $limit;
                   } else {
                       $params[] = $values['custom_merchant_id'];
                       $query = '
                           SELECT logs.datecreated, logs.mobilephone, logs.process_by as terminal_id, logs.transactionid, td.location, cc.cardnumber, cc.cardkeyid
                               FROM cardprofiles logs
                               LEFT JOIN terminal_details td ON td.terminal_id=logs.process_by
                               INNER JOIN merchant_lookup_external le ON le.branch_id=logs.branch_id
                               INNER JOIN cardprofiles_cardnumber cc ON cc.cardprofileid=logs.id
                                 AND le.merchant_id = logs.merchant_id
                               WHERE logs.merchant_id = ?
                                 AND FROM_UNIXTIME(logs.datecreated) BETWEEN ? AND ?
                                 AND le.external_id = ?
                               ORDER BY logs.datecreated ASC
                                 '. $limit;
                   }
 
                   try {
                       $result = $this->_db_rex2->fetchAll($query, $params);
                   } catch (Zend_Db_Statement_Exception $e) {
                       $this->_raiseError(__METHOD__, $e->getMessage(), 911004);
                       return FALSE;
                   }
                   
                   return $result;
                       break;                
               default:
                   $this->_raiseError(__METHOD__, 'Invalid type parameter.', $this->getErrorCode());
                   return false;
                   break;
           }
           foreach ($values['from_description'] as $from_desc) {
               $desc[] = 'LEFT(c2c.from_description,'. strlen($from_desc) .')=?';
               $params[] = $from_desc;
           }
           $desc = '(' . implode(' OR ', $desc) . ')';
           if ($values['custom_merchant_id'] == 'superadmin') {
               $query =
                   'SELECT c2c.dateprocess, c2c.process_by as terminal_id, c2c.messageid, c2c.'.$card_direction.'_cardnumber as cardnumber, c2c.to_amount, td.location
                       '.$addtl_fields.'
                       FROM logs_rex2api_cardfunctions_cardtocardtransfer c2c
                       LEFT JOIN terminal_details td ON td.terminal_id=c2c.process_by
                       '.$addtl_joins.'
                       WHERE c2c.merchant_id = ?
                         AND FROM_UNIXTIME(c2c.dateprocess) BETWEEN ? AND ?
                         AND '.$desc.'
                         AND c2c.branch_id = 0
                         AND c2c.issuccess = 1
                       ORDER BY c2c.dateprocess ASC
                         '. $limit;
           } else {
               $params[] = $values['custom_merchant_id'];
               $query =
                   'SELECT c2c.dateprocess, c2c.process_by as terminal_id, c2c.messageid, c2c.'.$card_direction.'_cardnumber as cardnumber, c2c.to_amount, td.location
                       '.$addtl_fields.'
                       FROM logs_rex2api_cardfunctions_cardtocardtransfer c2c
                       LEFT JOIN terminal_details td ON td.terminal_id=c2c.process_by
                       '.$addtl_joins.'
                       INNER JOIN merchant_lookup_external le ON le.branch_id=c2c.branch_id
                         AND le.merchant_id = c2c.merchant_id
                       WHERE c2c.merchant_id = ?
                         AND FROM_UNIXTIME(c2c.dateprocess) BETWEEN ? AND ?
                         AND '.$desc.'
                         AND le.external_id = ?
                         AND c2c.issuccess = 1
                       ORDER BY c2c.dateprocess ASC
                         '. $limit;
           }
           try {
               $result = $this->_db_rex2->fetchAll($query, $params);
           } catch (Zend_Db_Statement_Exception $e) {
               $this->_raiseError(__METHOD__, $e->getMessage(), 911004);
               return FALSE;
           }
           return $result;
       }
   }
 
   public function getTransactionSummary($values = array()) {
       $user_data = $this->_getMerchantSessionInfo($values['sessionid']);
       if (!isset($values['sessionid'], $values['merchant_id'], $values['type'])) {
           $this->_raiseError(__METHOD__, 'Incomplete parameters', $this->getErrorCode());
           return FALSE;
       } elseif (!$user_data) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       } else {
           $params = array($values['merchant_id']);
           switch ($values['type']) {
               case 'cardload':
                   $values['from_description'] = array('POS CARD LOAD', 'CARD LOAD');
                   break;
               case 'cashout':
                   $values['from_description'] = array('POS CASHOUT', 'CASH OUT');
                   break;
               case 'purchase':
                   $values['from_description'] = array('POS TRX SALE');
                   break;
               case 'activation':
                   //added by bom 2/28/11 to disallow merchant-level (custom_merchants) users from accessing other merchant's reports
                   $filter = '';
                   $mtid = array("89195","94301");
                   $activation_table = in_array($values['merchant_id'], $mtid) ? 'logs_rex2api_cardfunctions_setcardpin' : 'logs_rex2api_cardfunctions_setcardstatus';
                   if ($user_data[0]['branchid'] != '0') {
                       $filter = ' AND logs.branch_id=? ';
                       $params[] = $user_data[0]['branchid'];
                   } else {
                       $query2 = '
                           SELECT logs.branch_id, "superadmin" AS merchant_id, "Superadmin Branch" AS merchant_name, count( * ) AS transactions
                               FROM ' .$activation_table. ' logs
                               WHERE logs.merchant_id = ?
                                 AND logs.branch_id = 0
                                 AND FROM_UNIXTIME(logs.dateprocess) BETWEEN ? AND ?
                                 AND logs.issuccess = 1
                               GROUP BY logs.branch_id';
                   }
                   $query = '
                       SELECT logs.branch_id, le.external_id as merchant_id, mb.name as merchant_name, count( * ) AS transactions
                           FROM ' .$activation_table. ' logs
                           INNER JOIN merchant_branches mb ON logs.branch_id = mb.branchid
                             AND logs.merchant_id = mb.merchantid
                           INNER JOIN merchant_lookup_external le ON mb.branchid = le.branch_id
                             AND mb.merchantid = le.merchant_id
                           WHERE logs.merchant_id = ?
                             '.$filter.'
                             AND FROM_UNIXTIME(logs.dateprocess) BETWEEN ? AND ?
                             AND logs.issuccess = 1
                           GROUP BY logs.branch_id';
                   $params[] = $values['date_from'];
                   $params[] = $values['date_to'];
                   try {
                       $result = $this->_db_rex2->fetchAll($query, $params);
                       $result2 = $this->_db_rex2->fetchAll($query2, $params);
                   } catch (Zend_Db_Statement_Exception $e) {
                       $this->_raiseError(__METHOD__, $e->getMessage(), 911004);
                   }
                   if (!(is_array($result) && count($result) > 0)) {
                       $result = &$result2;
                   } elseif (is_array($result2) && count($result2) > 0) {
                       $result = array_merge($result, $result2);
                   }
                   return $result;
                   break;
               case "registered":
                       $filter = '';
                       if($values['datetype']=='daily'){
                       $cur_date = substr($values['date_from'],0,10);
                       $date_range = "AND FROM_UNIXTIME(logs.datecreated) LIKE '{$cur_date}%'";
                   } else {
                       $date_range = "AND FROM_UNIXTIME(logs.datecreated) BETWEEN '{$values['date_from']}' AND '{$values['date_to']}'";
                   }
                   if ($user_data[0]['branchid'] != '0') {
                       $filter = " AND logs.branch_id='{$user_data[0]['branchid']}'";
                   } else {
                       $query2 = '
                           SELECT logs.branch_id, "superadmin" AS merchant_id, "Superadmin Branch" AS merchant_name, count( * ) AS transactions
                               FROM cardprofiles logs
                               WHERE logs.merchant_id = '.$values['merchant_id'].'
                                 AND logs.branch_id = 0
                                 '.$date_range.'
                               GROUP BY logs.branch_id';
                   }                    
                   $query = '
                       SELECT logs.branch_id, le.external_id as merchant_id, mb.name as merchant_name, count( * ) AS transactions
                           FROM cardprofiles logs
                           INNER JOIN merchant_branches mb ON logs.branch_id = mb.branchid
                             AND logs.merchant_id = mb.merchantid
                           INNER JOIN merchant_lookup_external le ON mb.branchid = le.branch_id
                             AND mb.merchantid = le.merchant_id
                           WHERE logs.merchant_id = '.$values['merchant_id'].'
                             '.$filter.'
                             '.$date_range.'
                           GROUP BY logs.branch_id';
 
                   try {
                       $dateTimeZoneGmt    = new DateTimeZone("GMT");
                                                $dateTimeZoneNassau = new DateTimeZone("America/Nassau");
                                                $dateTimeGmt        = new DateTime($values['date_from'], $dateTimeZoneGmt);
                                                $timeOffset         = $dateTimeZoneNassau->getOffset($dateTimeGmt)/3600;
                                                $plus                           = ((int)$timeOffset>0)?'+':'';  
                                                $tz                                     = $plus.$timeOffset;
                                                
                                        $this->_db_rex2->query("SET time_zone = '{$tz}:00'");
                       $result  = $this->_db_rex2->query($query)->fetchAll();
                       $result2 = $this->_db_rex2->query($query2)->fetchAll();
                   } catch (Zend_Db_Statement_Exception $e) {
                       $this->_raiseError(__METHOD__, $e->getMessage(), 911004);
                   }
                   if (!(is_array($result) && count($result) > 0)) {
                       $result = &$result2;
                   } elseif (is_array($result2) && count($result2) > 0) {
                       $result = array_merge($result, $result2);
                   }
                   return $result;
               default:
                   $this->_raiseError(__METHOD__, 'Invalid type parameter.', $this->getErrorCode());
                   return false;
                   break;
           }
           foreach ($values['from_description'] as $from_desc) {
               $desc[] = 'LEFT(c2c.from_description,'. strlen($from_desc) .')=?';
               $params[] = $from_desc;
           }
           $desc = '(' . implode(' OR ', $desc) . ')';
           $params[] = $values['date_from'];
           $params[] = $values['date_to'];
 
           
           //added by bom 2/28/11 to disallow merchant-level (custom_merchants) users from accessing other merchant's reports
           $filter = '';
           try {
               if ($user_data[0]['branchid'] != '0') {
                   $filter = ' AND c2c.branch_id=? ';
                   $params[] = $user_data[0]['branchid'];
                   $result2 = array();
               } else {
                   $query2 =
                       'SELECT c2c.branch_id, "superadmin" as merchant_id, "Superadmin Branch" AS merchant_name, count( * ) AS transactions, sum( to_amount ) AS total_amount
                           FROM logs_rex2api_cardfunctions_cardtocardtransfer c2c
                           WHERE c2c.merchant_id = ?
                             AND '.$desc.'
                             AND c2c.branch_id = 0
                             AND FROM_UNIXTIME(c2c.dateprocess) BETWEEN ? AND ?
                             AND c2c.issuccess = 1
                           GROUP BY c2c.branch_id';
                   $result2 = $this->_db_rex2->fetchAll($query2, $params);
               }
               
               $query =
                   'SELECT c2c.branch_id, le.external_id AS merchant_id, mb.name AS merchant_name, count( * ) AS transactions, sum( to_amount ) AS total_amount
                       FROM logs_rex2api_cardfunctions_cardtocardtransfer c2c
                       INNER JOIN merchant_branches mb ON c2c.branch_id = mb.branchid
                       AND c2c.merchant_id = mb.merchantid
                       INNER JOIN merchant_lookup_external le ON mb.branchid = le.branch_id
                       AND mb.merchantid = le.merchant_id
                       WHERE c2c.merchant_id = ?
                        AND '.$desc.'
                         AND FROM_UNIXTIME(c2c.dateprocess) BETWEEN ? AND ?
                        '.$filter.'
                         AND c2c.issuccess = 1
                       GROUP BY c2c.branch_id';
               $result = $this->_db_rex2->fetchAll($query, $params);
           } catch (Zend_Db_Statement_Exception $e) {
               $this->_raiseError(__METHOD__, $e->getMessage(), 911004);
           }
           if (!(is_array($result) && count($result) > 0)) {
               $result = &$result2;
           } elseif (is_array($result2) && count($result2) > 0) {
               $result = array_merge($result, $result2);
           }
           return $result;
       }
   }
 
   public function updateFullProfileMerchantList()
   {
       $merchants = $this->_db_rex2->select()
                          ->from('vas_full_profile_update_merchants', array('merchantid'))
                          ->query()->fetchAll();
                          
       if (is_array($merchants) && count($merchants) > 0) {
           return $merchants;
       }
       $this->_raiseError(__METHOD__, 'No available merchants', $this->getErrorCode());
       return false;
   }
   
   public function updateFullProfileAddId(array $values)
   {
       $ids = array('profileid'=>$values['profileid'], 'merchantid'=>$values['merchantid']);
       $query = $this->_db_rex2->insert('vas_full_profile_update_list', $ids);
       
       if($query){
               return true;
       }
       
       $this->_raiseError(__METHOD__, 'Unable to save data', $this->getErrorCode());
       return false;
   }
   
   public function updateFullProfileIdList()
   {
       $profileid = $this->_db_rex2->select()
                          ->from('vas_full_profile_update_list', array('profileid'))
                          ->query()->fetchAll();
                          
       if (is_array($profileid) && count($profileid) > 0) {
           return $profileid;
       }
       $this->_raiseError(__METHOD__, 'No available Profile Id', $this->getErrorCode());
       return false;
   }
   
    /**
     * Loyalty API'S
     *
     */
   public function getTransactionType($merchant_id){
       $transaction_type = $this->_db_rex2->select()
                                          ->from('loyalty_merchant_transaction_types')
                                          ->where('merchant_id=?',$merchant_id)
                                          ->order('transaction_type')
                                          ->query()->fetchAll();
 
       if (!is_array($transaction_type) || count($transaction_type) == 0) {
               $this->_raiseError(__METHOD__, 'No available primary transaction type', 30004);
               return false;
       }
       
       $loyalty_primary = $this->_db_rex2->select()
                                        ->from('loyalty_primary_transaction_types')
                                        ->where('merchant_id=?',$merchant_id)
                                        ->query()->fetchAll();
       
       $_transaction_type = array();        
       foreach ($transaction_type as $tt){
               $flag = false;
               foreach ($loyalty_primary as $lp){
                       if($tt['transaction_type']==$lp['transaction_type']){
                               $trans = array_merge($tt, $lp);
                               $_transaction_type[] = $trans;
                               $flag = true;
                       }
               }
               if($flag === false){
                       $_transaction_type[] = $tt;                     
               }
       }
 
       return $_transaction_type;        
   }
   
   /**
     * Get Other Loyalty Transaction Type
     *
     * @param unknown_type $merchant_id
     * @return unknown
     */
   public function getOtherTransactionType($merchant_id){
       $other_transaction_type = $this->_db_rex2->select()
                                                    ->from('loyalty_transaction_types_per_merchant')
                                                    ->where('merchant_id=?', $merchant_id)
                                                    ->query()->fetchAll();
        
       if (!is_array($other_transaction_type) && count($other_transaction_type) == 0) {
               $this->_raiseError(__METHOD__, 'No available Other Loyalty Transaction Type', 30004);
               return false;
       }
       
       return $other_transaction_type;        
   }
   
   /**
     * check if loyalty enable
     *
     * @param unknown_type $merchant_id
     * @return unknown
     */
   public function checkIfLoyaltyEnable($id, $category='0')
   {
       $field = ($category=='0')?'merchant_id':'external_id';
       $merchant_list = $this->_db_rex2->select()
                                   ->from('loyalty_merchants_list')
                                   ->where("{$field}=?", $id);
                
                if($category=='0'){
                        $merchant_list->where('category=?', $category);
                }
                
                $merchant_list = $merchant_list->query()->fetchAll();
       
       if (is_array($merchant_list) && count($merchant_list) > 0) {
               return $merchant_list;
       }
       
       $this->_raiseError(__METHOD__, 'Loyalty module is not enable for this merchant', 30005);
       return false;
   }
   
   /**
     * Save Loyalty Primary Transaction Type
     *
     * @param array $values
     * @return unknown
     */
   public function saveLoyaltyPrimaryTransactionType(array $values)
   {
       require_once "Richard/Validate.php";
       
       $loyalty_category_prefix = "loyalty_points_cat_";
       $loyalty_category_table  = $loyalty_category_prefix.$values['loyalty_points_cat'];
       
       // {{{ Check basic required fields
       $required_params = array('merchant_id', 'transaction_type', 'loyalty_points_cat');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
       
       //check if already exist in loyalty primary transaction type
       $exist = $this->_db_rex2->select()
                  ->from('loyalty_primary_transaction_types')
                  ->where('merchant_id = ?', $values['merchant_id'])
                  ->where('transaction_type = ?', $values['transaction_type'])
                  ->where('loyalty_points_cat = ?', $values['loyalty_points_cat'])
                  ->query()->fetchAll();
       
       if(count($exist)>0){
               $this->_raiseError(__METHOD__,"Transaction failed: Data already exist", 30000);
           return false;
       }
       
       if($this->_db_rex2->insert('loyalty_primary_transaction_types', $values)){
               return true;
//              unset($values['loyalty_points_cat']);                   
//              $id = $this->_db_rex2->lastInsertId();
//              $values['source_id'] = (int) $id;
//              $save_in_cat = $this->_db_rex2->insert($loyalty_category_table, $values);
//              if($save_in_cat){
//                      return array("source_id"=>$id);
//              } else {
//                      $delete = $this->_db_rex2->delete('loyalty_primary_transaction_types', "lptt_id={$id}");
//                      $this->_raiseError(__METHOD__,"Transaction failed: Unable to save the record.", 30001);
//              return false;
//              }
       } else {
               $this->_raiseError(__METHOD__,"Transaction failed: Unable to save the record.", 30001);
           return false;
       }
       
       return false;
   }
   
   /**
     * Get Loyalty Primary Transaction Type
     *
     * @param array $values
     */
   public function getLoyaltyPrimaryTransactionType(array $values)
   {
       require_once "Richard/Validate.php";
       
       $loyalty_category_prefix = "loyalty_points_cat_";
       $loyalty_category_table  = $loyalty_category_prefix.$values['loyalty_points_cat'];
       
       // {{{ Check basic required fields
       $required_params = array('merchant_id', 'transaction_type', 'loyalty_points_cat');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
       
       //query transaction
       $primary_loyalty = $this->_db_rex2->select()
                                        ->from($loyalty_category_table)
                                        ->where("merchant_id=?", $values['merchant_id'])
                                        ->where("transaction_type=?", $values['transaction_type'])
                                        ->query()->fetchAll();
                                        
//        $primary_loyalty = $this->_db_rex2->select()
//                                       ->from($loyalty_category_table ." as a")
//                                       ->join('loyalty_merchant_transaction_types as b', "a.transaction_type=b.transaction_type", array("transaction_name"))
//                                       ->where("a.merchant_id=?", $values['merchant_id'])
//                                       ->where("b.merchant_id=?", $values['merchant_id'])
//                                       ->where("a.transaction_type=?", $values['transaction_type'])
//                                       ->query()->fetchAll();
                                         
       if(count($primary_loyalty)>0){
               foreach ($primary_loyalty as $key=>$val){
                       $primary_loyalty[$key]['loyalty_points_cat'] = $values['loyalty_points_cat'];
               }
       }
       return $primary_loyalty;
   }
   
   /**
     * Get Other loyalty transaction type
     *
     * @param array $values
     * @return unknown
     */
   public function getLoyaltyOtherTransactionType(array $values)
   {
       require_once "Richard/Validate.php";
       
       $loyalty_category_prefix = "loyalty_points_cat_";
       $loyalty_category_table  = $loyalty_category_prefix.$values['loyalty_points_cat'];
       
       // {{{ Check basic required fields
       $required_params = array('merchant_id', 'transaction_type', 'loyalty_points_cat');
       $required_fields = Richard_Validate::isEmptyArray($required_params,$values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
       
       //query transaction
       $other_loyalty = $this->_db_rex2->select()
                                  ->from($loyalty_category_table ." as a")
                                  ->join('loyalty_transaction_types_per_merchant as b', "a.transaction_type=b.transaction_type", array("description", "schedule_flag", "schedule_start", "schedule_end"))
                                  ->where("a.merchant_id='{$values['merchant_id']}' AND a.transaction_type='{$values['transaction_type']}'")
                                  ->query()->fetchAll();
                                         
       if(count($other_loyalty)>0){
               $other_loyalty[0]['loyalty_points_cat'] = $values['loyalty_points_cat'];
       }
       return $other_loyalty;
   }
   
   /**
     * Assign Loyalty Points
     *
     * @param array $values
     */
   public function assignPrimaryLoyaltyPoints(array $values)
   {
       require_once "Richard/Validate.php";
       
       $loyalty_category_prefix = "loyalty_points_cat_";
       $loyalty_category_table  = $loyalty_category_prefix.$values['loyalty_points_cat'];
       
       // {{{ Check basic required fields
       switch (trim($values['loyalty_points_cat'])) {
               case "fixed":
                                $required_params = array('source_id',
                                                                         'merchant_id',
                                                                         'transaction_type',
                                                                         'description',
                                                                         'amount',
                                                                         'currency',
                                                                         'points',
                                                                         'template');
                        $primary_params = array(
                                'source_id'               =>$values['source_id'],
                                'merchant_id'     =>$values['merchant_id'],
                                'transaction_type'=>$values['transaction_type'],
                                'description'     =>$values['description'],
                                'amount'          =>$values['amount'],
                                'currency'        =>$values['currency'],
                                'points'          =>$values['points'],
                                'template'        =>$values['template'],
                        );
                       break;
               case "range":
                       $required_params = array('source_id',
                                                                         'merchant_id',
                                                                         'transaction_type',
                                                                        'description',
                                                                        'from_amount',
                                                                        'to_amount',
                                                                        'currency',
                                                                        'points',
                                                                        'template');
                       $primary_params = array(
                               'source_id'               =>$values['source_id'],
                                'merchant_id'     =>$values['merchant_id'],
                                'transaction_type'=>$values['transaction_type'],
                                'description'     =>$values['description'],
                                'from_amount'     =>$values['from_amount'],
                                'to_amount'       =>$values['to_amount'],
                                'currency'        =>$values['currency'],
                                'points'          =>$values['points'],
                                'template'        =>$values['template'],
                        );
                       break;
               default:
                       break;
       }
       
       $required_fields = Richard_Validate::isEmptyArray($required_params,$values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
       
       if(!is_array($primary_params)){
               $this->_raiseError(__METHOD__,"Transaction failed: Invalid loyalty points category.", 30007);
               return false;
       }
       
       if($this->_db_rex2->insert($loyalty_category_table, $primary_params)){
               return true;
       } else {
               $this->_raiseError(__METHOD__,"Transaction failed: Unable to save the record.", 30001);
               return false;
       }
       
       return false;
   }
   
   /**
     * Assign Other Loyalty Points
     *
     * @param array $values
     * @return unknown
     */
   public function assignOtherLoyaltyPoints(array $values)
   {
       require_once "Richard/Validate.php";
       
       $loyalty_category_prefix = "loyalty_points_cat_";
       $loyalty_category_table  = $loyalty_category_prefix.$values['loyalty_points_cat'];
       
       // {{{ Check basic required fields
       if($values['loyalty_points_cat']=='fixed'){
               if($values['schedule_flag']=='normal'){
                       $required_params = array('description', 'amount', 'currency', 'points', 'template', 'schedule_start', 'schedule_end');
               } else {
                       $required_params = array('description', 'points', 'template', 'schedule_start', 'schedule_end');
               }
               $other_params = array(
                       'description'=>$values['description'],
                       'amount'     =>$values['amount'],
                       'currency'   =>$values['currency'],
                       'points'     =>$values['points'],
                       'template'   =>$values['template'],
               );
       } elseif ($values['loyalty_points_cat']=='range'){
               $other_params = array(
                       'description'=>$values['description'],
                       'from_amount'=>$values['from_amount'],
                       'to_amount'  =>$values['to_amount'],
                       'currency'   =>$values['currency'],
                       'points'     =>$values['points'],
                       'template'   =>$values['template'],
               );
               $required_params = array('description', 'from_amount', 'to_amount', 'currency', 'points', 'template', 'schedule_start', 'schedule_end');
       }
       $required_fields = Richard_Validate::isEmptyArray($required_params,$values);
 
       if ($required_fields !== true) {
           $this->_raiseError(__METHOD__,$required_fields);
           return false;
       }
       $source_id        = $values['source_id'];
       $merchant_id      = $values['merchant_id'];
       $trasanction_type = $values['transaction_type'];
       $update_where     = "merchant_id={$merchant_id} AND source_id={$source_id} AND transaction_type={$trasanction_type}";
       
       $update_other_loyalty = $this->_db_rex2->update($loyalty_category_table, $other_params, $update_where);
       
       $per_merchant_params = array(
               'schedule_start'=>$values['schedule_start'],
               'schedule_end'  =>$values['schedule_end'],
       );
       
       $update_merchant_where = "merchant_id={$merchant_id} AND transaction_type={$trasanction_type}";
       $update_other_loyalty_per_merchant = $this->_db_rex2->update('loyalty_transaction_types_per_merchant', $per_merchant_params, $update_merchant_where);
       
       if($update_other_loyalty || $update_other_loyalty_per_merchant){
               return true;
       } else {
               $this->_raiseError(__METHOD__,"Transaction failed: Unable to save the record.", 30001);
               return false;
       }
       
       return false;
   }
               ->order("transaction_date ASC")
               ->query()->fetchAll();
       if(is_array($select) && count($select)>0){
           return $select;
       }
       
       return array();
   }
   
   public function resendSMSActivationMessage($sessionid, $cardnumber)
   {
       $check_sessionid = $this->_getMerchantSessionInfo($sessionid);
       if (!$check_sessionid) {
           $this->_raiseError(__METHOD__, 'Requesting User ID does not exists', $this->getErrorCode());
           return false;
       }
       
       //sms notification per merchant
       $activation_notification = array(
           '92608'=>"Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>FirstName/LastName/4 Digit Pin.",
           '94301'=>"Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>Firstname<dot>Last Name<dot>PIN",
           '17891'=>"Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>Firstname<dot>Last Name<dot>PIN",
           '53703'=>"Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>Firstname<dot>Last Name<dot>PIN",
           '00000'=>"Congratulations, you have successfully registered your account. To activate, kindly reply ACT<space>4 Digit Pin.",
       );
 
       require_once "Richard/Modules/CardFunctions.php";
       require_once "Richard/System/Core.php";
       
       $user_data = array();
       $user_data = Richard_System_Core::getCardProfileByCard($cardnumber);
       if (!$user_data) {
           $this->_raiseError(__METHOD__, 'Card Profile does not exists', $this->getErrorCode());
           return false;
       }
       
       try {
           $services_options = array(
               'merchant_id' => $user_data['merchant_id'],
               'branch_id' => $user_data['branch_id'],
               'platform_requestor' => 'MMS-' . $user_data['transactionid'],
               'process_by' => $user_data['username']
           );
 
           $services = Richard_Modules_CardFunctions::init($services_options);
 
           $params = array('cardnumber' => $cardnumber);
 
           if ($services->getCardStatus($params)) {
               $resp_data = $services->getResponseData();
               $cardstatus = array_flip(Richard_System_Core::getCardStatus());
               if ($resp_data['cardstatus'] == 0) {
                   //resend the sms notification
                   if(isset($user_data['mobilephone']) && $user_data['mobilephone']!= ""){
                       $sms = Richard_Modules_SMS::initByCard($cardnumber);
                       $params = array(
                           'message' => $activation_notification[$user_data['merchant_id']],
                           'mobilenumber' => $user_data['mobilephone'],
                       );
                       $sms->sendSMS($params);
                   }
               }
 
               return $response = array('messageid' => $resp_data['messageid'],
                   'statuscode' => $resp_data['cardstatus'],
                   'statusdesc' => $cardstatus[$resp_data['cardstatus']]
               );
           } else {
               $this->_raiseError(__METHOD__, $services->getError(), $services->getResponseCode());
               return false;
           }
       } catch (Richard_Exception $e) {
           $this->_raiseError(__METHOD__, $re->getMessage(), $re->getErrorCode());
           return false;
       }
   }
   
   public function getBranchWorkStations($values = array()) {
       $this->_values = &$values;
       
       try {
                $sql = "SELECT ws.id, ws.name, ws.description
                                FROM merchant_branch_ws ws
                                INNER JOIN merchant_branches mb ON mb.id = ws.branch_id
                                WHERE mb.merchantid = ?
                                 AND mb.branchid = ?
                                ORDER BY ws.name ASC";
                                 
                $stmt = $this->_db_rex2->prepare($sql);
                
                if ($stmt->execute (array(
                                        $this->_values['merchantid'],
                                        $this->_values['branchid'])))
                {
                        $result = $stmt->fetchAll();
                        return count($result) ? $result : false;
                }
                
       } catch (Richard_Exception $e) {
               $this->_raiseError(__METHOD__, $re->getMessage(), $re->getErrorCode());
       }
       
       return false;
   }
   
   public function getUserWorkStations($values = array()) {
       $this->_values = &$values;
   
       try {
               $sql = "SELECT ws.id, ws.name, ws.description
                                FROM merchant_branch_ws ws
                                INNER JOIN merchant_branch_ws_users wsu ON wsu.ws_id = ws.id
                                INNER JOIN merchant_branches mb ON mb.id = ws.branch_id
                                WHERE mb.merchantid = ?
                                 AND mb.branchid = ?
                                 AND wsu.user_id = ?
                                ORDER BY ws.name ASC";
   
               $stmt = $this->_db_rex2->prepare($sql);
   
               if ($stmt->execute (array(
                               $this->_values['merchantid'],
                               $this->_values['branchid'],
                               $this->_values['userid'])))
               {
                       $result = $stmt->fetchAll();
                       return count($result) ? $result : false;
               }
   
       } catch (Richard_Exception $e) {
               $this->_raiseError(__METHOD__, $re->getMessage(), $re->getErrorCode());
       }
   
       return false;
   }
}
 
?>